定義
$geoNear指定した点に近いものから遠いものの順にドキュメントを出力します。
$geoNearステージのプロトタイプ形式は次のとおりです。{ $geoNear: { <geoNear options> } } $geoNear演算子は、次の オプションを含む$geoNearドキュメントを受け入れます。次のように、すべての距離を処理ドキュメントの座標系と同じ単位で指定します。フィールドタイプ説明distanceFieldstring
計算された距離を含む出力フィールド。埋め込みドキュメント内のフィールドを指定するには、ドット表記を使用します。
distanceMultiplier数値
任意。クエリによって返されるすべての距離に乗じる係数。たとえば、
distanceMultiplierを使用して、球面クエリによって返されるラジアンを地球の半径で乗算してキロメートルに変換します。includeLocsstring
任意。距離の計算に使用されるロケーションを識別する出力フィールドを指定します。このオプションは、ロケーション フィールドに複数の場所が含まれているロケーションに便利です。埋め込みドキュメント内のフィールドを指定するには、ドット表記を使用します。
key任意。距離を計算するときに使用する地理空間インデックス フィールドを指定します。
コレクションに複数の
2dインデックスや複数の2dsphereインデックスがある場合は、使用するインデックス付きフィールドパスを指定するためにkeyオプションを使用する必要があります。「 使用する地理空間インデックスの指定 」で多くの例を紹介しています。複数の
2dインデックスまたは複数の2dsphereインデックスがあり、keyを指定しない場合、MongoDB はエラーを返します。keyを指定せず、2dインデックスが最大で 1 つしかない、もしくは2dsphereインデックスが 1 つしかない場合、または両方ある場合、MongoDB は使用する2dインデックスを最初に探します。2dインデックスが存在しない場合、MongoDB は使用する2dsphereインデックスを探します。時系列コレクションで、
$geoNearのkeyフィールドを指定する必要があります。maxDistance数値
任意。 ドキュメントが存在できる中心点からの最大距離。 MongoDBは、中心点から指定した距離内にあるドキュメントに結果を制限します。 バージョン 7.2 以降では、数値に変換される有効な定数式を指定できます。
指定された点が GeoJSON の場合は距離をメートル単位で指定し、指定された点が legacy coordinate pairs の場合はラジアン単位で指定します。
minDistance数値
任意。 ドキュメントが存在できる中心点からの最小距離。 MongoDB は、中心点から指定された距離の外側にあるドキュメントに結果を制限します。 バージョン 7.2 以降では、数値に変換される有効な定数式を指定できます。
GeoJSON データの場合はメートル単位で、legacy coordinate pairs の場合はラジアン単位で距離を指定します。
nearGeoJSON ポイントまたは legacy coordinate pair
queryドキュメント
任意。クエリに一致するドキュメントに結果を制限します。クエリ構文は、通常の MongoDB 読み取り操作クエリ構文です。
$nearquery$geoNearステージの フィールドに 述語を指定することはできません。時系列コレクションでは、 の
queryフィールドは使用できません。$geoNearsphericalブール値
任意。MongoDB が 2 点間の距離を計算する方法を決定します。
trueの場合、MongoDB は$nearSphereセマンティクスを使用し、球面ジオメトリで距離を計算します。falseの場合、MongoDB は$nearセマンティクスを使用します。2dsphere インデックスには球面ジオメトリ、2d インデックスには平面ジオメトリを使用します。
デフォルト: false。
動作
距離計算
$geoNear は、入力ドキュメントの境界の最も近い点に基づいて距離を計算します。
例、入力ドキュメントが形状の場合、$geoNear は指定された点に最も近い形状の境界上の点を識別し、指定された点と形状の最も近い点との間の距離を出力します。
Considerations
$geoNear を使用する場合は、次の点に注意してください。
$geoNearはパイプラインの最初のステージとしてのみ使用できます。distanceFieldオプションを含める必要があります。distanceFieldオプションは、計算された距離を格納するフィールドを指定します。$geoNearは地理空間インデックスが必要です。コレクションに複数の地理空間インデックスがある場合は、
keysパラメータを使用して、計算で使用するフィールドを指定します。地理空間インデックス が1 つしかない場合、$geoNearは暗黙的にインデックス付きフィールドを計算に使用します。
$nearquery$geoNearステージの フィールドに 述語を指定することはできません。$geoNearは、デフォルトで 100 ドキュメントの制限はなくなりました。nearパラメータは let オプション と バインドされた let オプション をサポートします。時系列コレクション内の任意のフィールドで パイプライン演算子を使用できます。ただし、時系列コレクションの の フィールドは使用できません。
$geoNearquery$geoNearMongoDB 8.0 以降、
$near、$nearSphere、および$geoNearは、指定された GeoJSON ポイントの型がPointであることを検証します。それ以外の入力型はエラーを返します。
例
次のドキュメントを使用してコレクション 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インデックスがあります。次の集計では、 $geoNear を使用して、中心 [ -73.99279 , 40.719296 ] から最大 2 メートルのロケーションにあり、category が Parks に等しいドキュメントを検索します。
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フィールド(計算に使用するロケーションを含む)
最小距離
次の例では、minDistance オプションを使用して、ドキュメントが存在できる中心点からの最小距離を指定します。次の集計では、ロケーションが中心([ -73.99279 , 40.719296 ])から 2 メートル以上離れており、category が Parks に等しいすべてのドキュメントが検索されます。
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 } } ])
オプションを使用した $geoNearlet
この例では、次のことが行われます。
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 離れたロケーションcategoryはParksに等しいです。
{ _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 ] } } }
Bound オプションを使用した $geoNearlet
let オプションは、$geoNear クエリで使用できる変数をバインドできます。
この例では、$lookup は次の変数を使用します。
let($ptを定義するため)$geoNearpipelineの$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" }
keylocation次の例では、$geoNear legacyオプションを使用して、集計で 操作に$limit フィールド値ではなく フィールド値を使用する指定にしています。また、パイプラインは を使用して最大5 ドキュメントを返します。
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 } }
このページのC#の例では、Atlasサンプルデータセット の sample_mflix.theatersコレクションを使用します。MongoDB Atlasクラスターを無料で作成して、サンプルデータセットをロードする方法については、 MongoDB .NET/ C#ドライバーのドキュメントの「 開始 」を参照してください。
次の Theater、Location、および Address クラスは、sample_mflix.theaters コレクション内のドキュメントをモデル化します。
public class Theater { public ObjectId Id { get; set; } [] public int TheaterId { get; set; } [] public Location Location { get; set; } [] public double? Distance { get; set; } } public class Location { [] public Address Address { get; set; } [] public GeoJsonPoint<GeoJson2DGeographicCoordinates> Geo { get; set; } } [] public class Address { [] public string City { get; set; } [] public string State { get; set; } }
MongoDB .NET/C# ドライバーを使用して $geoNear ステージを集計パイプラインに追加するには、GeoNear() メソッドを PipelineDefinition オブジェクトで呼び出します。
このメソッドはMongoDB .NET/ C#ドライバー v3.4 以降でのみ使用できます。
最大距離
次の例では、指定された点から半径 8000 メートル以内のドキュメントを、距離の昇順で返すパイプラインステージを作成します。このコードには、location.address.state フィールドの値が "NJ" であるドキュメントのみと一致する Query パラメーターが含まれています。このコードは、計算された距離を出力ドキュメントの distance フィールドに保存します。
var pipeline = new EmptyPipelineDefinition<Theater>() .GeoNear( GeoJson.Point(GeoJson.Geographic(-74.1, 40.95)), new GeoNearOptions<Theater, Theater> { DistanceField = "distance", MaxDistance = 8000, Key = "location.geo", Query = Builders<Theater>.Filter.Eq(t => t.Location.Address.State, "NJ"), });
最小距離
次の例では、指定された点の 8000 メートルの半径外にある最初の 4 一致するドキュメントを、距離の昇順で返します。コードには、location.address.stateフィールドの値が "NJ" であるドキュメントのみに一致する Query パラメーターが含まれています。また、コードは計算された距離を出力ドキュメントの distanceフィールドに保存します。
var pipeline = new EmptyPipelineDefinition<Theater>() .GeoNear( GeoJson.Point(GeoJson.Geographic(-74.1, 40.95)), new GeoNearOptions<Theater, Theater> { DistanceField = "distance", MinDistance = 8000, Key = "location.geo", Query = Builders<Theater>.Filter.Eq(t => t.Location.Address.State, "NJ"), }) .Limit(4);
このページのNode.js の例では、Atlasサンプルデータセット の sample_mflixデータベースを使用します。無料のMongoDB Atlas cluster を作成し、サンプルデータセットをロードする方法については、 MongoDB Node.jsドライバーのドキュメントの開始を参照してください。
MongoDB Node.jsドライバーを使用して $geoNear ステージを集計パイプラインに追加するには、パイプラインオブジェクトで $geoNear 演算子を使用します。
最大距離
次の例では、指定された点の半径 8000 メートル以内にあるドキュメントを、距離の昇順で返すパイプラインステージを作成します。コードには、location.address.stateフィールドの値が "NJ" であるドキュメントのみに一致する queryフィールドが含まれています。また、コードは計算された距離を出力ドキュメントの distanceフィールドに保存します。次に、この例では集計パイプラインを実行します。
const pipeline = [ { $geoNear: { near: { type: "Point", coordinates: [-74.1, 40.95] }, distanceField: "distance", maxDistance: 8000, query: { "location.address.state": "NJ" }, spherical: true } } ]; const cursor = collection.aggregate(pipeline); return cursor;
最小距離
次の例では、指定された点の 8000 メートルの半径外にある最初の 4 一致するドキュメントを、距離の昇順で返します。コードには、location.address.stateフィールドの値が "NJ" であるドキュメントのみに一致する queryフィールドが含まれています。このコードは、出力ドキュメントの distanceフィールドにも計算された距離を保存します。
const pipeline = [ { $geoNear: { near: { type: "Point", coordinates: [-74.1, 40.95] }, distanceField: "distance", minDistance: 8000, query: { "location.address.state": "NJ" }, spherical: true }, }, { $limit: 4 } ]; const cursor = collection.aggregate(pipeline); return cursor;
詳細
関連するパイプラインステージの詳細については、$limitガイドを参照してください。