Docs Menu
Docs Home
/
MongoDB マニュアル
/ / /

$geoNear(集計)

項目一覧

  • 定義
  • 動作
$geoNear

指定した点に近いものから遠いものの順にドキュメントを出力します。

注意

MongoDBlimit numは、$geoNear ステージの オプションと オプション、および100 ドキュメントのデフォルト制限を削除します。$geoNearの結果を制限するには、 $geoNearステージと $limitステージを使用します。

$geoNearステージのプロトタイプ形式は次のとおりです。

{ $geoNear: { <geoNear options> } }

$geoNear 演算子は、次の $geoNear オプションを含むドキュメント を受け入れます。次のように、すべての距離を処理ドキュメントの座標系と同じ単位で指定します。

フィールド
タイプ
説明
distanceField
string
計算された距離を含む出力フィールド。埋め込みドキュメント内のフィールドを指定するには、ドット表記を使用します。
distanceMultiplier
数値
任意。クエリによって返されるすべての距離に乗じる係数。たとえば、distanceMultiplier を使用して、球面クエリによって返されるラジアンを地球の半径で乗算してキロメートルに変換します。
includeLocs
string
任意。距離の計算に使用されるロケーションを識別する出力フィールドを指定します。このオプションは、ロケーション フィールドに複数の場所が含まれているロケーションに便利です。埋め込みドキュメント内のフィールドを指定するには、ドット表記を使用します。
key

任意。距離を計算するときに使用する地理空間インデックス フィールドを指定します。

コレクションに複数の 2d インデックスや複数の 2dsphere インデックスがある場合は、使用するインデックス付きフィールドパスをkey オプションに指定する必要があります。「使用する地理空間インデックスの指定」で多くの例を紹介しています。

複数の 2d インデックスまたは複数の 2dsphere インデックスがあり、key を指定しない場合、MongoDB はエラーを返します。

key を指定せず、2d インデックスが最大で 1 つしかない、もしくは 2dsphere インデックスが 1 つしかない場合、または両方ある場合、MongoDB は使用する 2d インデックスを最初に探します。2d インデックスが存在しない場合、MongoDB は使用する 2dsphere インデックスを探します。

maxDistance
数値

任意。ドキュメントが存在できる中心点からの最大距離。MongoDBは、中心点から指定した距離内にあるドキュメントに結果を制限します。

指定された点が GeoJSON の場合は距離をメートル単位で指定し、指定された点が legacy coordinate pairs の場合はラジアン単位で指定します。

minDistance
数値

任意。ドキュメントが存在できる中心点からの最小距離。MongoDB は、中心点から指定された距離の外側にあるドキュメントに結果を制限します。

GeoJSON データの場合はメートル単位で、legacy coordinate pairs の場合はラジアン単位で距離を指定します。

near
GeoJSON ポイントまたは legacy coordinate pair

最も近いドキュメントを検索する点。

2dsphereインデックスを使用する場合は、点を GeoJSON ポイントまたは legacy coordinate pair として指定できます。

2d インデックスを使用する場合は、点を legacy coordinate pair として指定します。

query
ドキュメント

任意。クエリに一致するドキュメントに結果を制限します。クエリ構文は、通常の MongoDB 読み取り操作クエリ構文です。

$geoNear ステージの query フィールドに $near 述語を指定することはできません。

spherical
ブール値

任意。MongoDB が 2 点間の距離を計算する方法を決定します。

  • true の場合、MongoDB は $nearSphere セマンティクスを使用し、球面ジオメトリで距離を計算します。

  • false の場合、MongoDB は $near セマンティクスを使用します。2dsphere インデックスには球面ジオメトリ、2d インデックスには平面ジオメトリを使用します。

デフォルト: false。

$geoNear を使用する場合は、次の点に注意してください。

  • $geoNear は、パイプラインの最初のステージとしてのみ使用できます。

  • distanceField オプションを含める必要があります。distanceField オプションは、計算された距離を格納するフィールドを指定します。

  • $geoNear地理空間インデックスが必要です。

    コレクションに複数の地理空間インデックスがある場合は、keys パラメーターを使用して、計算で使用するフィールドを指定します。地理空間インデックスが 1 つしかない場合は、$geoNear は暗黙的にインデックス付きフィールドを計算に使用します。

次のドキュメントを使用してコレクション 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" } )

注意

MongoDB は、$geoNear ステージの limit オプションおよび num オプション、ならびに 100 個のドキュメントのデフォルト制限を削除します。$geoNear の結果を制限するには、$geoNear ステージを $limit ステージとともに使用します。

上記の places コレクションは 2dsphere インデックスを保有しています。次の集計では、$geoNear を使用して、中心 [ -73.99279 , 40.719296 ] から最大 2 メートルのロケーションにあり、categoryParks に等しいドキュメントを検索します。

db.places.aggregate([
{
$geoNear: {
near: { type: "Point", coordinates: [ -73.99279 , 40.719296 ] },
distanceField: "dist.calculated",
maxDistance: 2,
query: { category: "Parks" },
includeLocs: "dist.location",
spherical: true
}
}
])

集計により次の結果が返されます。

{
"_id" : 8,
"name" : "Sara D. Roosevelt Park",
"category" : "Parks",
"location" : {
"type" : "Point",
"coordinates" : [ -73.9928, 40.7193 ]
},
"dist" : {
"calculated" : 0.9539931676365992,
"location" : {
"type" : "Point",
"coordinates" : [ -73.9928, 40.7193 ]
}
}
}

一致するドキュメントには、次の 2 つの新しいフィールドが含まれます。

  • dist.calculated フィールド(計算された距離を含む)、および

  • dist.location フィールド(計算に使用するロケーションを含む)

注意

MongoDB は、$geoNear ステージの limit オプションおよび num オプション、ならびに 100 個のドキュメントのデフォルト制限を削除します。$geoNear の結果を制限するには、$geoNear ステージを $limit ステージとともに使用します。

次の例では、minDistance オプションを使用して、ドキュメントが存在できる中心点からの最小距離を指定します。次の集計では、ロケーションが中心([ -73.99279 , 40.719296 ])から 2 メートル以上離れており、categoryParks に等しいすべてのドキュメントが検索されます。

db.places.aggregate([
{
$geoNear: {
near: { type: "Point", coordinates: [ -73.99279 , 40.719296 ] },
distanceField: "dist.calculated",
minDistance: 2,
query: { category: "Parks" },
includeLocs: "dist.location",
spherical: true
}
}
])

この例では、次のことが行われます。

  • let オプションは、配列の値である [-73.99279,40.719296] を変数 $pt に設定するために使用されます。

  • $pt は、$geoNear ステージの near パラメーターに let オプションとして指定されます。

db.places.aggregate(
[
{
"$geoNear":
{
"near":"$$pt",
"distanceField":"distance",
"maxDistance":2,
"query":{"category":"Parks"},
"includeLocs":"dist.location",
"spherical":true
}
}
],
{
"let":{ "pt": [ -73.99279, 40.719296 ] }
}
)

この集計は、次の情報を含むすべてのドキュメントを返します。

  • let 変数で定義された点から最大 2 m 離れたロケーション

  • categoryParks に等しいです。

{
_id: ObjectId("61715cf9b0c1d171bb498fd7"),
name: 'Sara D. Roosevelt Park',
location: { type: 'Point', coordinates: [ -73.9928, 40.7193 ] },
category: 'Parks',
distance: 1.4957325341976439e-7,
dist: { location: { type: 'Point', coordinates: [ -73.9928, 40.7193 ] } }
},
{
_id: ObjectId("61715cf9b0c1d171bb498fd6"),
name: 'Central Park',
location: { type: 'Point', coordinates: [ -73.97, 40.77 ] },
category: 'Parks',
distance: 0.0009348548688841822,
dist: { location: { type: 'Point', coordinates: [ -73.97, 40.77 ] } }
}

let オプションは、$geoNear クエリで使用できる変数をバインドできます。

この例では、$lookup は次の変数を使用します。

  • let$ptを定義するため)

  • pipeline の中の $geoNear

  • $pt $geoNear パイプライン ステージ内で near を定義するために

db.places.aggregate( [
{
$lookup: {
from: "places",
let: { pt: "$location" },
pipeline: [
{
$geoNear: {
near: "$$pt",
distanceField: "distance"
}
}
],
as: "joinedField"
}
},
{
$match: { name: "Sara D. Roosevelt Park" }
}
] );

この集計は、次を含むドキュメントを返します。

  • メインのドキュメントとしての「Sara D. Roosevelt Park」ドキュメント。

  • 距離を計算するための $pt 変数を使用したサブドキュメントとしての places コレクション内の各ドキュメント。

{
_id: ObjectId("61715cf9b0c1d171bb498fd7"),
name: 'Sara D. Roosevelt Park',
location: { type: 'Point', coordinates: [ -73.9928, 40.7193 ] },
category: 'Parks',
joinedField: [
{
_id: ObjectId("61715cf9b0c1d171bb498fd7"),
name: 'Sara D. Roosevelt Park',
location: { type: 'Point', coordinates: [ -73.9928, 40.7193 ] },
category: 'Parks',
distance: 0
},
{
_id: ObjectId("61715cf9b0c1d171bb498fd6"),
name: 'Central Park',
location: { type: 'Point', coordinates: [ -73.97, 40.77 ] },
category: 'Parks',
distance: 5962.448255234964
},
{
_id: ObjectId("61715cfab0c1d171bb498fd8"),
name: 'Polo Grounds',
location: { type: 'Point', coordinates: [ -73.9375, 40.8303 ] },
category: 'Stadiums',
distance: 13206.535424939102
}
]
}

locationフィールドに 2dsphere インデックスがあり、legacy フィールドに 2d インデックスがある places コレクションを考えてみましょう。

places コレクションのドキュメントには次のようなものがあります。

{
"_id" : 3,
"name" : "Polo Grounds",
"location": {
"type" : "Point",
"coordinates" : [ -73.9375, 40.8303 ]
},
"legacy" : [ -73.9375, 40.8303 ],
"category" : "Stadiums"
}

次の例では、key オプションを使用して、集計で $geoNear 操作に legacy フィールド値ではなく location フィールド値を使用する指定にしています。また、パイプラインは $limit を使用して最大 5 のドキュメントを返します。

注意

MongoDB は、$geoNear ステージの limit オプションおよび num オプション、ならびに 100 個のドキュメントのデフォルト制限を削除します。$geoNear の結果を制限するには、$geoNear ステージを $limit ステージとともに使用します。

db.places.aggregate([
{
$geoNear: {
near: { type: "Point", coordinates: [ -73.98142 , 40.71782 ] },
key: "location",
distanceField: "dist.calculated",
query: { "category": "Parks" }
}
},
{ $limit: 5 }
])

集計により次の結果が返されます。

{
"_id" : 8,
"name" : "Sara D. Roosevelt Park",
"location" : {
"type" : "Point",
"coordinates" : [
-73.9928,
40.7193
]
},
"category" : "Parks",
"dist" : {
"calculated" : 974.175764916902
}
}
{
"_id" : 1,
"name" : "Central Park",
"location" : {
"type" : "Point",
"coordinates" : [
-73.97,
40.77
]
},
"legacy" : [
-73.97,
40.77
],
"category" : "Parks",
"dist" : {
"calculated" : 5887.92792958097
}
}

戻る

$fill

項目一覧