MongoDB は地理空間データに対するクエリ操作をサポートしています。このセクションでは、MongoDB の地理空間機能を紹介します。
地理空間データ
MongoDB では、地理空間データを GeoJSON オブジェクトまたは legacy coordinate pairs として保存できます。
GeoJSON オブジェクト
地球のような球体上の形状を計算するには、ロケーションデータを GeoJSON オブジェクトとして保存します。
GeoJSON データを指定するには、以下の埋め込みドキュメントを使用します。
GeoJSON オブジェクトタイプを指定する
typeという名前のフィールドとオブジェクトの座標を指定する
coordinatesというフィールド。
<field>: { type: <GeoJSON type> , coordinates: <coordinates> }
重要
緯度と経度の座標を指定する場合は、最初に経度、次に緯度を指定します。
有効な経度の値は、
-180以上、180以下です。有効な緯度の値は
-90以上、90以下です。
たとえば、GeoJSONポイントを指定するには、次のようにします。
location: { type: "Point", coordinates: [-73.856077, 40.848447] }
MongoDBでサポートされている GeoJSON オブジェクトのリストと例については、「GeoJSON オブジェクト」を参照してください。
GeoJSON オブジェクトに対する MongoDB の地理空間クエリは球体上で計算されます。MongoDB は、GeoJSON オブジェクトに対する地理空間クエリに WGS84 参照システムを使用します。
Legacy Coordinate Pairs
2d インデックスインデックスを使用して平面(ユークリッド)計算にレガシー coordinate pairs を使用します。球面計算を実行するには、レガシーペアを GeoJSONPoint に変換し、2 dsphere インデックスインデックスを使用します。
データを legacy coordinate pairs として指定するには、配列(推奨)または埋め込みドキュメントのいずれかを使用できます。
- 配列:
<field>: [ <x>, <y> ] 経度と緯度を使用する場合は、最初に経度、次に緯度を指定します。
<field>: [ <longitude>, <latitude> ] 有効な経度の値は、
-180以上、180以下です。有効な緯度の値は
-90以上、90以下です。
- 埋め込みドキュメント:
<field>: { <field1>: <x>, <field2>: <y> } 経度と緯度を使用する場合、最初のフィールドは 経度 、2 番目のフィールドは 緯度 である必要があります。
<field>: { <field1>: <longitude>, <field2>: <latitude> } 有効な経度の値は、
-180以上、180以下です。有効な緯度の値は
-90以上、90以下です。
一部の言語ではオブジェクトフィールドの順序が保持されないため、 レガシー coordinate pairs には配列を使用します。
地理空間インデックス
地理空間インデックスは、 GeoJSON オブジェクトまたはレガシー coordinate pairs として保存されたデータに対するクエリをサポートします。地理空間インデックスを使用すると、地理空間データに対するクエリのパフォーマンスを向上させたり、特定の地理空間クエリを実行したりできます。
MongoDB は 2 種類の地理空間インデックスを提供します。
2dsphere インデックスは、球体上のジオメトリを解釈するクエリをサポートします。
2d インデックス。平面上のジオメトリを解釈するクエリをサポートします。
地理空間インデックスの詳細については、「地理空間インデックス」を参照してください。
地理空間クエリ
注意
球状データのクエリに 2d インデックスを使用すると、誤った結果やエラーが返されることがあります。たとえば、2d インデックスでは、北極と南極が入っている球面クエリはサポートされていません。
地理空間クエリ演算子
MongoDB には以下のような地理空間クエリ演算子があります。例を含む詳細については、各リファレンスページを参照してください。
名前 | 説明 |
|---|---|
GeoJSON ジオメトリと交差するジオメトリを選択します。2dsphere インデックスは | |
境界となる GeoJSON ジオメトリ内のジオメトリを選択します。2dsphere と 2d インデックスは | |
点に近接する地理空間オブジェクトを返します。地理空間インデックスが必要です。 | |
球上の点に近接する地理空間オブジェクトを返します。地理空間インデックスが必要です。 |
注意
時系列コレクションは、2dsphere インデックスに対するクエリからの地理空間データをソートするための $geoNear 集計ステージのみをサポートしています。時系列コレクションでは $near および $nearSphere 演算子は使用できません。
地理空間集約ステージ
MongoDB には、次の地理空間集約パイプライン ステージがあります。
ステージ | 説明 |
|---|---|
例を含む詳細については、$geoNear リファレンス ページを参照してください。
地理空間モデル
MongoDB 地理空間クエリは、平面または球面上のジオメトリを解釈できます。
2dsphere インデックスは球面クエリ(球面上のジオメトリを解釈するクエリ)のみをサポートします。
2d インデックスは平面クエリ(平面上のジオメトリを解釈するクエリ)や、一部の球面クエリをサポートします。2d インデックスは一部の球面クエリをサポートしていますが、これらの球面クエリに 2d インデックスを使用するとエラーが発生する可能性があります。可能であれば、球面クエリには 2dsphere インデックスを使用してください。
次の表は、各地理空間操作で使用される地理空間クエリ演算子とサポートされているクエリを一覧表示したものです。
操作 | 球面/平面クエリ | ノート |
|---|---|---|
球面 |
| |
平面 | ||
| 球面 | GeoJSONポイントと 球面クエリの場合、 |
| 球面 | 代わりに GeoJSONポイントを使用してください。 |
| 球面 | |
| 平面 | |
| 平面 | |
| 平面 | |
| 球面 | |
球面 | ||
球面 | ||
平面 |
Atlas での地理空間クエリの実行
例
次のドキュメントを使用してコレクション places を作成します。
db.places.insertMany( [ { name: "Central Park", location: { type: "Point", coordinates: [ -73.97, 40.77 ] }, category: "Parks" }, { name: "Sara D. Roosevelt Park", location: { type: "Point", coordinates: [ -73.9928, 40.7193 ] }, category: "Parks" }, { name: "Polo Grounds", location: { type: "Point", coordinates: [ -73.9375, 40.8303 ] }, category: "Stadiums" } ] )
以下の操作は、location フィールドに2dsphere インデックスを作成します。
db.places.createIndex( { location: "2dsphere" } )
上の places コレクションには 2dsphere インデックスがあります。以下のクエリは、$near 演算子を使用し、指定された GeoJSONポイントから 1000 ~ 5000 メートル離れたドキュメントを、最も近いものから最も遠いものの順に並べ替えて返します。
db.places.find( { location: { $near: { $geometry: { type: "Point", coordinates: [ -73.9667, 40.78 ] }, $minDistance: 1000, $maxDistance: 5000 } } } )
以下の操作では、$geoNear 集計操作を使用して、クエリフィルター { category:
"Parks" } に一致するドキュメントを、指定された GeoJSONポイントに最も近いものから最も遠いものの順に並べ替えて返します。
db.places.aggregate( [ { $geoNear: { near: { type: "Point", coordinates: [ -73.9667, 40.78 ] }, spherical: true, query: { category: "Parks" }, distanceField: "calcDistance" } } ] )