2d インデックスは、球面ジオメトリを使用して距離を計算する特定のクエリ演算子をサポートします。 球面クエリ演算子は、距離にラジアンを使用します。 2d インデックスで球面クエリ演算子を使用するには、距離をラジアンに変換する必要があります。
2d インデックスは次の球面クエリ演算子をサポートします。
$geoNearオプション付きの パイプライン ステージspherical: true
このタスクについて
球状データのクエリに 2d インデックスを使用すると、誤った結果やエラーが返されることがあります。 たとえば、2d インデックスでは、北極と南極が入っている球面クエリはサポートされていません。
データが経度と緯度として保存され、球面に対してクエリを実行することが多い場合は、 2d インデックスではなく2dsphere インデックスを使用してください。
経度と緯度の座標を指定する場合は、最初に経度、次に緯度を指定します。
有効な経度の値は、
-180以上、180以下です。有効な緯度の値は
-90以上、90以下です。
手順
距離をラジアンに変換するには、距離測定と同じ単位で距離を球体(たとえば、地球)の半径で割ります。
地球の等価半径は約 3,963.2 マイルまたは 6,378.1 キロです。
例
次の例では、 $centerSphere演算子を使用してクエリを実行します。 $centerSphere演算子はラジアンを使用して距離を計算します。
contacts コレクションを次のように作成します。
db.contacts.insertMany( [ { name: "Evander Otylia", phone: "202-555-0193", address: [ 55.5, 42.3 ] }, { name: "Georgine Lestaw", phone: "714-555-0107", address: [ -74, 44.74 ] } ] )
addressフィールドにはlegacy coordinate pairs が含まれています。
マイルをラジアンに変換
次のクエリでは、 addressフィールドが中心点[ -72, 44 ]と半径 200 マイルの円内にあるドキュメントが返されます。
db.contacts.find( { address: { $geoWithin: { $centerSphere: [ [ -72, 44 ] , 200 / 3963.2 ] } } } )
出力:
[ { _id: ObjectId("647e565c6cdaf4dc323ec92d"), name: 'Georgine Lestaw', phone: '714-555-0107', address: [ -74, 44.74 ] } ]
前のクエリでは、200 マイルをラジアンに変換するために、指定されたマイルを 3963.2 で割った。
キロメートルをラジアンに変換する
次のクエリでは、 addressフィールドが中心点[ 55, 42 ]と半径 500 キロの円内にあるドキュメントが返されます。
db.contacts.find( { address: { $geoWithin: { $centerSphere: [ [ 55, 42 ] , 500 / 6378.1 ] } } } )
出力:
[ { _id: ObjectId("647e565c6cdaf4dc323ec92c"), name: 'Evander Otylia', phone: '202-555-0193', address: [ 55.5, 42.3 ] } ]
前のクエリでは、500 キロをラジアンに変換するために、指定されたキロは 6378.1 で割られています。