Docs Menu
Docs Home
/ / /
Kotlin コルーチン
/ / /

地理空間で検索する

このガイドでは、 Kotlinドライバー を使用して地理空間データをクエリする方法を学習できます。MongoDBでサポートされているさまざまな地理空間データ形式についても学習できます。

地理空間データとは、地球の表面上の地理的ロケーションを表すデータです。 地理空間データの例には、次のようなものがあります。

  • 映画館のロケーション

  • 国境

  • 自転車走行ルート

  • ニューヨーク市の犬の運動エリア

MongoDB に地理空間データを保存してクエリするには、 GeoJSONを使用します。 GeoJSON は、インターネット エンジニアリング タスク 強制(ETF)によって作成されたデータ形式です。

GeoJSON の MongoDB 本社のロケーションは次のとおりです。

"location" : {
"type": "point",
"coordinates": [-73.986805, 40.7620853]
}

GeoJSON の詳細な情報については、 公式 IETF 仕様を参照してください。

位置は地球上の単一の場所を表し、2 つまたは 3 つの数値を含む配列として与えられます。

  • 最初の位置の経度(必須)

  • 2 番目の位置の緯度(必須)

  • 3 番目の位置での高度(任意)

重要

経度、次に緯度

GeoJSON では、座標は最初に経度、次に緯度の順に並べられます。地理座標系の規則では、一般に緯度が最初に、経度が 2 番目に記載されているため、これは意外かもしれません。作業に使用する他のツールがどのような形式を使用しているかを必ず確認しましょう。OpenStreetMap や Google マップなどの一般的なツールでは、座標が最初に緯度、次に経度としてリストされます。

GeoJSON オブジェクトのタイプによって幾何学的形状が決まります。 幾何学的形状は位置で構成されています。

以下に、一般的な GeoJSON の型と、それらを位置で指定する方法を示します。

  • Point: 単一の位置。これは暗号化の場所を表すことができます。

  • LineString: 2 つ以上の位置の配列。これにより、一連の線セグメントを形成します。これは、中国のすべての国のルートを表す可能性があります。

  • Polygon: 最初と最後の位置が同じで、スペースを含む位置の配列。これは バチカン市国内の土地 を表すことができます

MongoDBで使用できる形状の詳細については、サーバー マニュアルの GeoJSON を参照してください。

GeoJSON形式で保存されたデータをクエリするには、GeoJSON データを含むフィールドを2dsphereインデックスに追加します。次のスニペットは、Indexes ビルダを使用して location.geoフィールドに 2dsphereインデックスを作成します。

collection.createIndex((Indexes.geo2dsphere("location.geo")))

Indexes ビルダの詳細については、「 インデックス ビルダガイド 」をご覧ください。

2 次元ユークリッド平面上の x 座標と y 座標を使用して地理空間データを保存できます。2 次元平面上の座標はレガシー coordinate pairsと呼ばれます。

legacy coordinate pairsは次の構造をしています。

{ "location" : [ x, y ] }

フィールド値には 2 つの値の配列が含まれており、1 つ目は x 軸の値を表し、2 つ目は y 軸の値を表します。

レガシー coordinate pairs として保存されたデータをクエリするには、 レガシー coordinate pairs を含むフィールドを2dインデックスに追加する必要があります。次のスニペットは、Indexes ビルダを使用して coordinatesフィールドに 2dインデックスを作成します。

collection.createIndex((Indexes.geo2d("coordinates")))

Indexes ビルダの詳細については、インデックス ビルダガイドをご覧ください。

レガシー coordinate pairs の詳細については、サーバー マニュアルの地理空間クエリガイドの「 Legacy Coordinate Pairs 」セクションを参照してください。

Tip

サポートされている演算子

球面(2dsphere )と平面(2d )インデックスは、同じクエリ演算子の一部をサポートしていますが、すべてではありません。演算子とそのインデックスの互換性の完全なリストを表示するには、サーバー マニュアルの「地理空間クエリガイド」の「地理空間クエリ演算子」セクションを参照してください。

地理空間クエリは、 クエリ演算子 とクエリ パラメータとして GeoJSON シェイプ で構成されます。

地理空間データをクエリするには、次のいずれかのクエリ演算子を使用します。

  • $near

  • $geoWithin

  • $nearSphere

  • $geoIntersects 2DSPHERE インデックスが必要です

これらのクエリ演算子は、MongoDB Kotlin ドライバー内でFiltersビルダ クラスのnear()geoWithin()nearSphere() 、およびgeoIntersects()ユーティリティ メソッドを使用して指定できます。

地理空間クエリ演算子の詳細については、サーバー マニュアルの「地理空間クエリ演算子」ガイドの「地理空間クエリ演算子」セクションを参照してください。

Filters ビルダの詳細については、フィルター ビルダガイド を参照してください。

地理空間クエリで使用する形状を指定するには、 Kotlinドライバーの PositionPointLineStringPolygon クラスを使用します。

GeoJSON シェイプ クラスの詳細については、GeoJSONパッケージ APIドキュメント を参照してください。

次の例では、 MongoDB Atlasサンプルデータセットを使用します。 Kotlin Driver クイック スタートガイドでは、独自の無料階層 Atlas クラスターをセットアップする方法と、サンプルデータセットをロードする方法について学びます。

例では、サンプル データセットの sample_mflix データベースの theaters コレクションを使用します。

このセクションの例には、次のインポートが必要です。

import com.mongodb.client.model.geojson.Point
import com.mongodb.client.model.geojson.Polygon
import com.mongodb.client.model.geojson.Position
import com.mongodb.client.model.Filters.near
import com.mongodb.client.model.Filters.geoWithin
import com.mongodb.client.model.Projections.fields
import com.mongodb.client.model.Projections.include
import com.mongodb.client.model.Projections.excludeId

サンプルドキュメントは、次のKotlinデータクラスによってモデル化されます。

data class Theater(
val theaterId: Int,
val location: Location
) {
data class Location(
val address: Address,
val geo: Point
) {
data class Address(
val street1: String,
val street2: String? = null,
val city: String,
val state: String,
val zipcode: String
)
}
}

結果ドキュメントは、次のKotlinデータクラスによってモデル化されます。

data class TheaterResults(
val location: Location
) {
data class Location(
val address: Address
) {
data class Address(
val city: String
)
}
}

theatersコレクションには、 "${Theater::location.name}.${Theater.Location::geo.name}"フィールドの2dsphereインデックスがすでに含まれています。

点に最も近いドキュメントから最も遠いドキュメントの順に検索して返すには、 Filtersビルダ クラスのnear()静的ユーティリティ メソッドを使用します。 near()メソッドは、 $nearクエリ演算子を使用してクエリを構築します。

次の例では、Atlas Triggers から 10000 から 5000 メートルの間にある映画館をクエリします。

val database = client.getDatabase("sample_mflix")
val collection = database.getCollection<TheaterResults>("theaters")
val centralPark = Point(Position(-73.9667, 40.78))
val query = Filters.near(
"${Theater::location.name}.${Theater.Location::geo.name}", centralPark, 10000.0, 5000.0
)
val projection = Projections.fields(
Projections.include(
"${Theater::location.name}.${Theater.Location::address.name}.${Theater.Location.Address::city.name}"),
Projections.excludeId()
)
val resultsFlow = collection.find(query).projection(projection)
resultsFlow.collect { println(it) }
TheaterResults(location=Location(address=Address(city=Bronx)))
TheaterResults(location=Location(address=Address(city=New York)))
TheaterResults(location=Location(address=Address(city=New York)))
TheaterResults(location=Location(address=Address(city=Long Island City)))
TheaterResults(location=Location(address=Address(city=New York)))
TheaterResults(location=Location(address=Address(city=Secaucus)))
TheaterResults(location=Location(address=Address(city=Jersey City)))
TheaterResults(location=Location(address=Address(city=Elmhurst)))
TheaterResults(location=Location(address=Address(city=Flushing)))
TheaterResults(location=Location(address=Address(city=Flushing)))
TheaterResults(location=Location(address=Address(city=Flushing)))
TheaterResults(location=Location(address=Address(city=Elmhurst)))

Tip

MongoDB は、GPS インスタンスと同じ参照システムを使用して、地球上の形状を計算します。

$near 演算子の詳細については、サーバー マニュアルの $near に関する参照を参照してください。

指定した形状内の地理空間データを検索するには、 Filtersビルダ クラスのgeoWithin()静的ユーティリティ メソッドを使用します。 geoWithin()メソッドは、 $geoWithinクエリ演算子を使用してクエリを構築します。

次の例では、Long Expression の セクションで映画館を検索します。

val longIslandTriangle = Polygon(
listOf(
Position(-72.0, 40.0),
Position(-74.0, 41.0),
Position(-72.0, 39.0),
Position(-72.0, 40.0)
)
)
val projection = Projections.fields(
Projections.include(
"${Theater::location.name}.${Theater.Location::address.name}.${Theater.Location.Address::city.name}"),
Projections.excludeId()
)
val geoWithinComparison = Filters.geoWithin(
"${Theater::location.name}.${Theater.Location::geo.name}", longIslandTriangle
)
val resultsFlow = collection.find<TheaterResults>(geoWithinComparison)
.projection(projection)
resultsFlow.collect { println(it) }
TheaterResults(location=Location(address=Address(city=Baldwin))))
TheaterResults(location=Location(address=Address(city=Levittown)))
TheaterResults(location=Location(address=Address(city=Westbury)))
TheaterResults(location=Location(address=Address(city=Mount Vernon)))
TheaterResults(location=Location(address=Address(city=Massapequa)))

次の図は、 longIslandTriangle変数によって定義される多角形と、クエリによって返された映画館の場所を表すドットを示しています。

映画館を検索する長い言語の面積

$geoWithin 演算子の詳細については、サーバー マニュアルの $geoWithin 参照を参照してください。

戻る

返すフィールドを指定する

項目一覧