Overview
このガイドでは、 Kotlinドライバー を使用して地理空間データをクエリする方法を学習できます。MongoDBでサポートされているさまざまな地理空間データ形式についても学習できます。
地理空間データとは、地球の表面上の地理的ロケーションを表すデータです。 地理空間データの例には、次のようなものがあります。
映画館のロケーション
国境
自転車走行ルート
ニューヨーク市の犬の運動エリア
地球上の座標
MongoDB に地理空間データを保存してクエリするには、 GeoJSONを使用します。 GeoJSON は、インターネット エンジニアリング タスク 強制(ETF)によって作成されたデータ形式です。
GeoJSON の MongoDB 本社のロケーションは次のとおりです。
"location" : { "type": "point", "coordinates": [-73.986805, 40.7620853] }
GeoJSON の詳細な情報については、公式 IETF 仕様を参照してください。
GeoJSON の位置
位置は地球上の単一の場所を表し、2 つまたは 3 つの数値を含む配列として与えられます。
最初の位置の経度(必須)
2 番目の位置の緯度(必須)
3 番目の位置での高度(任意)
重要
経度、次に緯度
GeoJSON では、座標は最初に経度、次に緯度の順に並べられます。地理座標系の規則では、一般に緯度が最初に、経度が 2 番目に記載されているため、これは意外かもしれません。作業に使用する他のツールがどのような形式を使用しているかを必ず確認しましょう。OpenStreetMap や Google マップなどの一般的なツールでは、座標が最初に緯度、次に経度としてリストされます。
GeoJSON タイプ
GeoJSON オブジェクトのタイプによって幾何学的形状が決まります。 幾何学的形状は位置で構成されています。
以下に、一般的な GeoJSON の型と、それらを位置で指定する方法を示します。
Point: 単一の位置。これは暗号化の場所を表すことができます。LineString: 2 つ以上の位置の配列。これにより、一連の線セグメントを形成します。これは、中国のすべての国のルートを表す可能性があります。Polygon: 最初と最後の位置が同じで、スペースを含む位置の配列。これは バチカン市国内の土地 を表すことができます
MongoDBで使用できる形状の詳細については、サーバー マニュアルの GeoJSON を参照してください。
Index
GeoJSON形式で保存されたデータをクエリするには、GeoJSON データを含むフィールドを2dsphereインデックスに追加します。次のスニペットは、Indexes ビルダを使用して location.geoフィールドに 2dsphereインデックスを作成します。
collection.createIndex((Indexes.geo2dsphere("location.geo")))
Indexes ビルダの詳細については、インデックス ビルダガイドをご覧ください。
2D 平面上の座標
2 次元ユークリッド平面上の x 座標と y 座標を使用して地理空間データを保存できます。2 次元平面上の座標はレガシー coordinate pairsと呼ばれます。
legacy coordinate pairsは次の構造をしています。
{ "location" : [ x, y ] }
フィールド値には 2 つの値の配列が含まれており、1 つ目は x 軸の値を表し、2 つ目は y 軸の値を表します。
Index
レガシー coordinate pairs として保存されたデータをクエリするには、 レガシー coordinate pairs を含むフィールドを2dインデックスに追加する必要があります。 次のスニペットは、Indexes ビルダを使用して coordinatesフィールドに 2dインデックスを作成します。
collection.createIndex((Indexes.geo2d("coordinates")))
Indexes ビルダの詳細については、インデックス ビルダガイドをご覧ください。
レガシー coordinate pairs の詳細については、サーバー マニュアルの地理空間クエリガイドのレガシー coordinate pairsセクションを参照してください。
Tip
サポートされている演算子
球面(2dsphere)と平面(2d)インデックスは、同じクエリ演算子の一部をサポートしていますが、すべてではありません。演算子とそのインデックスの互換性の完全なリストを表示するには、サーバー マニュアルの「地理空間クエリガイド」の地理空間クエリ演算子セクションを参照してください。
地理空間クエリ
地理空間クエリは、 クエリ演算子 とクエリ パラメータとして GeoJSON シェイプ で構成されます。
クエリ演算子
地理空間データをクエリするには、次のいずれかのクエリ演算子を使用します。
$near$geoWithin$nearSphere$geoIntersects2DSPHERE インデックスが必要です
これらのクエリ演算子は、MongoDB Kotlin ドライバー内でFiltersビルダ クラスのnear() 、 geoWithin() 、 nearSphere() 、およびgeoIntersects()ユーティリティ メソッドを使用して指定できます。
地理空間クエリ演算子の詳細については、サーバー マニュアルの「地理空間クエリ演算子」ガイドの「地理空間クエリ演算子」セクションを参照してください。
Filters ビルダの詳細については、フィルター ビルダガイド を参照してください。
クエリ パラメータ
地理空間クエリで使用する形状を指定するには、 Kotlinドライバーの Position、Point、LineString、Polygon クラスを使用します。
GeoJSON シェイプ クラスの詳細については、GeoJSONパッケージ APIドキュメント を参照してください。
地理空間クエリの例
次の例では、MongoDB Atlasサンプルデータセットを使用します。独自の無料階層 Atlas クラスターを設定する方法と、サンプルデータセットをロードする方法については、 「 Kotlinドライバーを使い始める 」ガイドを参照してください。
例では、サンプル データセットの 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 参照を参照してください。