地理空間データとの連携
項目一覧
Overview
このガイドでは、地理空間データの扱い方、データ形式、インデックス、クエリについて説明します。地理空間データは、地球の表面上の地理的ロケーション、またはユークリッド平面上のデータを表します。
地理空間データの例には、次のようなものがあります。
映画館のロケーション
国境
自転車走行ルート
ニューヨーク市の犬の運動エリア
グラフ上の点
地理空間データの保存
MongoDB 内のすべての地理空間データは、次のいずれかの形式で保存されます。
GeoJSON は、地球のような球体上で地理空間データを表す形式です。
レガシー座標ペアは、ユークリッド平面上で地理空間データを表す形式です。
GeoJSON
GeoJSONを使用して、地球のような球体上で地理空間情報を表すデータを保存します。GeoJSON は、1 つ以上の位置と型で構成されます。
位置
位置は地球上の単一の場所を表し、コード内では次の値を含む配列として存在します。
最初の位置の経度(必須)
2 番目の位置の緯度(必須)
3 番目の位置での高度(任意)
ニューヨーク州ニューヨーク市にある MongoDB 本社の位置は、以下の通りです。
[]float64{-73.986805, 40.7620853}
重要
経度、次に緯度
GeoJSON では、座標は最初に経度、次に緯度の順に並べられます。地理座標系の規則では、一般に緯度が最初に、経度が 2 番目に記載されているため、これは意外かもしれません。作業に使用する他のツールがどのような形式を使用しているかを必ず確認しましょう。OpenStreetMap や Google マップなどの一般的なツールでは、座標が最初に緯度、次に経度としてリストされます。
タイプ
GeoJSON オブジェクトの型によって、それが表す幾何学的形状が決まります。幾何学的形状は位置で構成されています。
以下に、一般的な GeoJSON の型と、それらを位置で指定する方法を示します。
Point
: 単一つの位置。次のPoint
は MongoDB 本社の所在地を表しています。bson.D{ {"name", "MongoDB HQ"}, {"location", bson.D{ {"type", "Point"}, {"coordinates", []float64{-73.986805, 40.7620853}}, }}, } LineString
: 一連の線セグメントを形成する 2 つ以上の位置の配列。LineString
は、パス、ルート、境界、またはその他の線形地理空間データを表すことができます。LineString
次の 、中国の グレースウォール の セグメントを表します。bson.D{ {"name", "Great Wall of China"}, {"location", bson.D{ {"type", "LineString"}, {"coordinates", [][]float64{ {116.572, 40.430}, {116.570, 40.434}, {116.567, 40.436}, {116.566, 40.441}, }}}, }, } Polygon
: 最初と最後の位置が同じで、スペースを含む位置の配列。次のPolygon
は、バチカン市国内の土地を表しますbson.D{ {"name", "Vatican City"}, {"location", bson.D{ {"type", "Polygon"}, {"coordinates", [][][]float64{{ {12.446086, 41.901977}, {12.457952, 41.901559}, {12.455375, 41.907351}, {12.449863, 41.905186}, {12.446086, 41.901977}, }}}, }}, }
MongoDB で使用できる GeoJSON タイプの詳細については、 GeoJSON マニュアルの エントリを参照してください。
GeoJSON に関する明確な情報については、 公式 IETF 仕様 を参照してください。
Legacy Coordinate Pairs
legacy coordinate pairs を使用して、2 次元ユークリッド平面上の地理空間情報を表すデータを保存します。
フィールドには 2 つの値の配列が含まれており、1 つ目は x
軸の値を表し、2 つ目は y
軸の値を表している必要があります。
bson.D{{"center", []int16{0, 0}}}
legacy coordinate pairs の詳細については、legacy coordinate pairsに関する MongoDB Server のマニュアル ページを参照してください。
地理空間インデックス
地理空間データのクエリを有効にするには、データ形式に対応するインデックスを作成する必要があります。以下のインデックス型により、地理空間クエリが可能になります。
2dsphere
GeoJSON データ用2d
legacy coordinate pairs の場合
2dsphere
GeoJSON 形式で保存されたデータをクエリするには、type
と coordinates
の両方を含むフィールドを 2dsphere
インデックスに追加します。次の例では、 location
フィールドに 2dsphere
インデックスを作成します。
indexModel := mongo.IndexModel{ Keys: bson.D{{"location", "2dsphere"}}, } name, err := coll.Indexes().CreateOne(context.TODO(), indexModel) if err != nil { panic(err) }
2d
legacy coordinate pairs として保存されたデータをクエリするには、legacy coordinate pairs を含むフィールドを 2d
インデックスに追加する必要があります。次の例では、coordinates
フィールドに 2d
インデックスを作成します。
indexModel := mongo.IndexModel{ Keys: bson.D{{"location.coordinates", "2d"}}, } name, err := coll.Indexes().CreateOne(context.TODO(), indexModel) if err != nil { panic(err) }
地理空間クエリ
地理空間クエリを実行するには、フィールド名と地理空間クエリ演算子を使用してクエリフィルターを作成します。特定の地理空間クエリ演算子に追加のオプションを指定すると、返されるドキュメントを制限できます。
地理空間インデックスを作成していない場合は、地理空間クエリを有効にするために地理空間インデックスを作成する必要があります。
Tip
サポートされている演算子
球面( 2dsphere
)と平面( 2d
)のインデックスは、同じクエリ演算子の一部をサポートしていますが、すべてではありません。 演算子とインデックスの互換性の完全なリストについては、 地理空間クエリ に関するマニュアル エントリを参照してください。
クエリ演算子
地理空間データをクエリするには、次のいずれかのクエリ演算子を使用します。
$near
$geoWithin
$nearSphere
$geoIntersects
2DSPHERE インデックスが必要です
$near
演算子を使用する場合、次の距離演算子を指定できます。
$minDistance
$maxDistance
$geoWithin
演算子を使用する場合、次の図形演算子を指定できます。
$box
$polygon
$center
$centerSphere
地理空間クエリ演算子の詳細については、地理空間クエリに関するマニュアル エントリを参照してください。
例
次の例では、MongoDB Atlas サンプル データセットを使用します。 「 Atlas を使い始める 」ガイドに従って MongoDB Atlas の無料階層のデータベースにサンプル データセットをロードするか、 サンプル データセットをローカルの MongoDB インスタンスにインポートすることができます。
例では、サンプル データセットの sample_mflix
データベースの theaters
コレクションを使用します。theaters
コレクションには、 location.geo
フィールドに 2dsphere
インデックスが含まれています。
近接性によるクエリ
次の例では、ニューヨーク州ニューヨーク市にある MongoDB 本社から 1000 メートル以内にある location.geo
フィールドを持つドキュメントをクエリします。ドキュメントは最も近いものから最も遠いものへと返されます。
mongoDBHQ := bson.D{{"type", "Point"}, {"coordinates", []float64{-73.986805, 40.7620853}}} filter := bson.D{ {"location.geo", bson.D{ {"$near", bson.D{ {"$geometry", mongoDBHQ}, {"$maxDistance", 1000}, }}, }}, } var places []bson.D output, err := coll.Find(context.TODO(), filter) if err = output.All(context.TODO(), &places); err != nil { panic(err) } for _, place := range places { res, _ := bson.MarshalExtJSON(place, false, false) fmt.Println(string(res)) }
{"_id":{...},"theaterId":1908,"location":{"address":{...},"geo":{"type":"Point","coordinates":[-73.983487,40.76078]}}} {"_id":{...},"theaterId":1448,"location":{"address":{...},"geo":{"type":"Point","coordinates":[-73.982094,40.769882]}}}
範囲内のクエリ
次の例では、ニューヨーク州ニューヨーク市にある MongoDB 本社から 2000 メートル以内、3000 メートル以内にある location.geo
フィールドを持つドキュメントをクエリします。ドキュメントは最も近いものから最も遠いものへと返されます。
mongoDBHQ := bson.D{{"type", "Point"}, {"coordinates", []float64{-73.986805, 40.7620853}}} filter := bson.D{ {"location.geo", bson.D{ {"$nearSphere", bson.D{ {"$geometry", mongoDBHQ}, {"$minDistance", 2000}, {"$maxDistance", 3000}, }}, }}, } var places []bson.D output, err := coll.Find(context.TODO(), filter) if err = output.All(context.TODO(), &places); err != nil { panic(err) } for _, place := range places { res, _ := bson.MarshalExtJSON(place, false, false) fmt.Println(string(res)) }
{"_id":{...},"theaterId":482,"location":{...},"geo":{"type":"Point","coordinates":[-73.99295,40.74194]}}}
追加リソース
地理空間データの操作の詳細については、 地理空間データに関するマニュアル エントリを参照してください。
サポートされている GeoJSON タイプの詳細については、 GeoJSON のマニュアル エントリを参照してください。
地理空間クエリ演算子の詳細については、地理空間クエリに関するマニュアル エントリを参照してください。
Go ドライバーでのインデックス操作の詳細については、「 インデックス ガイド 」をご覧ください。