$geoNear (aggregation)

On this page本页内容

Definition定义

$geoNear

Outputs documents in order of nearest to farthest from a specified point.按距离指定点最近或最远的顺序输出文档。

Note注意

Starting in version 4.2, MongoDB removes the limit and num options for the $geoNear stage as well as the default limit of 100 documents. 从版本4.2开始,MongoDB删除了$geoNear阶段的limmitnum选项以及100个文档的默认限制。To limit the results of $geoNear, use the $geoNear stage with the $limit stage.要限制$geoNear的结果,请将$geoNear阶段与$limit阶段一起使用。

The $geoNear stage has the following prototype form:$geoNear阶段具有以下原型形式:

{ $geoNear: { <geoNear options> } }

The $geoNear operator accepts a document that contains the following $geoNear options. $geoNear运算符接受包含以下$geoNear选项的文档Specify all distances in the same units as those of the processed documents' coordinate system:以与已处理文档坐标系相同的单位指定所有距离:

Field字段Type类型Description描述
distanceFieldstringThe output field that contains the calculated distance. 包含计算距离的输出字段。To specify a field within an embedded document, use dot notation.要在嵌入文档中指定字段,请使用点符号
distanceMultipliernumberOptional. 可选。The factor to multiply all distances returned by the query. 乘以查询返回的所有距离的因子。For example, use the distanceMultiplier to convert radians, as returned by a spherical query, to kilometers by multiplying by the radius of the Earth.例如,使用distanceMultiplier将球形查询返回的弧度乘以地球半径,转换为千米。
includeLocsstringOptional. 可选。This specifies the output field that identifies the location used to calculate the distance. 这指定用于标识用于计算距离的位置的输出字段。This option is useful when a location field contains multiple locations. 当位置字段包含多个位置时,此选项非常有用。To specify a field within an embedded document, use dot notation.要在嵌入文档中指定字段,请使用点符号
key

Optional. 可选。Specify the geospatial indexed field to use when calculating the distance.指定计算距离时要使用的地理空间索引字段。

If your collection has multiple 2d and/or multiple 2dsphere indexes, you must use the key option to specify the indexed field path to use. 如果集合具有多个2d和/或多个2dsphere索引,则必须使用key选项指定要使用的索引字段路径。Specify Which Geospatial Index to Use provides a full example.指定要使用的地理空间索引提供了完整的示例。

If there is more than one 2d index or more than one 2dsphere index and you do not specify a key, MongoDB will return an error.如果存在多个2d索引或多个2dsphere索引,并且您没有指定key,MongoDB将返回一个错误。

If you do not specify the key, and you have at most only one 2d index and/or only one 2dsphere index, MongoDB looks first for a 2d index to use. 如果您没有指定key,并且您最多只有一个2d索引和/或只有一个2dsphere索引,MongoDB将首先查找要使用的2d索引。If a 2d index does not exists, then MongoDB looks for a 2dsphere index to use.如果2d索引不存在,则MongoDB将查找要使用的2dsphere索引。

New in version 4.0.在版本4.0中新增

maxDistancenumber

Optional. 可选。The maximum distance from the center point that the documents canbe. 文档可以到达的与中心点的最大距离。MongoDB limits the results to those documents that fall within the specified distance from the center point.MongoDB将结果限制在距离中心点指定距离内的文档。

Specify the distance in meters if the specified point is GeoJSON and in radians if the specified point is legacy coordinate pairs.如果指定点为GeoJSON,则以米为单位指定距离;如果指定点是传统坐标对,则以弧度为单位指定。

minDistancenumber

Optional. 可选。The minimum distance from the center point that the documents canbe. 距离文档可以到达的中心点的最小距离。MongoDB limits the results to those documents that fall outside the specified distance from the center point.MongoDB将结果限制在距离中心点指定距离之外的文档。

Specify the distance in meters for GeoJSON data and in radians for legacy coordinate pairs.指定GeoJSON数据的距离(以米为单位)和传统坐标对的距离(弧度为单位)。

nearGeoJSON point or legacy coordinate pairGeoJSON点或传统坐标对

The point for which to find the closest documents.查找最接近文档的点。

If using a 2dsphere index, you can specify the point as either a GeoJSON point or legacy coordinate pair.如果使用2dsphere索引,则可以将点指定为GeoJSON点或传统坐标对。

If using a 2d index, specify the point as a legacy coordinate pair.如果使用2d索引,请将点指定为传统坐标对。

querydocument

Optional. 可选。Limits the results to the documents that match the query. 将结果限制为与查询匹配的文档。The query syntax is the usual MongoDB read operation query syntax.查询语法是常用的MongoDB读取操作查询语法。

You cannot specify a $near predicate in the query field of the $geoNear stage.不能在$geoNear阶段的query字段中指定$near谓词。

sphericalboolean

Optional. 可选。Determines how MongoDB calculates the distance between two points:确定MongoDB如何计算两点之间的距离:

  • When true, MongoDB uses $nearSphere semantics and calculates distances using spherical geometry.如果为true,MongoDB使用$nearSphere语义并使用球形几何计算距离。
  • When false, MongoDB uses $near semantics: spherical geometry for 2dsphere indexes and planar geometry for 2d indexes.当为false时,MongoDB使用$near语义:2dsphere索引使用球面几何,2d索引使用平面几何。

Default: false.默认值:false

uniqueDocsboolean

Optional. 可选。If this value is true, the query returns a matching document once, even if more than one of the document's location fields match the query.如果该值为true,则即使文档的多个位置字段与查询匹配,查询也会返回一次匹配的文档。

Deprecated since version 2.6自2.6版以来已弃用: Geospatial queries no longer return duplicate results. 答:地理空间查询不再返回重复结果。The $uniqueDocs operator has no impact on results.$uniqueDocs运算符对结果没有影响。

Behavior行为

When using $geoNear, consider that:使用$geoNear时,请考虑:

  • You can only use $geoNear as the first stage of a pipeline.您只能将$geoNear用作管道的第一阶段。
  • You must include the distanceField option. 必须包含distanceField选项。The distanceField option specifies the field that will contain the calculated distance.distanceField选项指定包含计算距离的字段。
  • $geoNear requires a geospatial index.需要地理空间索引

    If you have more than one geospatial index on the collection, use the keys parameter to specify which field to use in the calculation. 如果集合中有多个地理空间索引,请使用keys参数指定要在计算中使用的字段。If you have only one geospatial index, $geoNear implicitly uses the indexed field for the calculation.如果只有一个地理空间索引,$geoNear隐式使用索引字段进行计算。

  • You cannot specify a $near predicate in the query field of the $geoNear stage.不能在$geoNear阶段的query字段中指定$near谓词。
  • Views视图 do not support geoNear operations (i.e. $geoNear pipeline stage).不支持geoNear操作(即$geoNear管道阶段)。
  • Starting in MongoDB 4.2, $geoNear no longer has a default limit of 100 documents.从MongoDB 4.2开始,$geoNear不再有100个文档的默认限制。
  • Starting in MongoDB 5.1, the near parameter supports the let option and bound let option.从MongoDB 5.1开始,near参数支持let选项绑定let选项
  • Starting in MongoDB 5.3, you can use the $geoNear pipeline operator with a:从MongoDB 5.3开始,您可以使用$geoNear管道运算符配合:

Examples示例

Create a collection places with the following documents:使用以下文档创建集合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"
   }
] )

The following operation creates a 2dsphere index on the location field:以下操作将在位置字段上创建2dsphere索引:

db.places.createIndex( { location: "2dsphere" } )

Maximum Distance最大距离

Note注意

Starting in version 4.2, MongoDB removes the limit and num options for the $geoNear stage as well as the default limit of 100 documents. 从版本4.2开始,MongoDB删除了$geoNear阶段的limitnum选项以及100个文档的默认限制。To limit the results of $geoNear, use the $geoNear stage with the $limit stage.要限制$geoNear的结果,请将$geoNear阶段与$limit阶段一起使用。

The places collection above has a 2dsphere index. 上面的places集合有一个2dsphere索引。The following aggregation uses $geoNear to find documents with a location at most 2 meters from the center [ -73.99279 , 40.719296 ] and category equal to Parks.以下聚合使用$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
     }
   }
])

The aggregation returns the following:聚合返回以下内容:

{
   "_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 ]
      }
   }
}

The matching document contains two new fields:匹配文档包含两个新字段:

  • dist.calculated field that contains the calculated distance, and包含计算距离的字段,并且
  • dist.location field that contains the location used in the calculation.包含计算中使用的位置的字段。

Minimum Distance最小距离

Note注意

Starting in version 4.2, MongoDB removes the limit and num options for the $geoNear stage as well as the default limit of 100 documents. 从版本4.2开始,MongoDB删除了$geoNear阶段的limitnum选项以及100个文档的默认限制。To limit the results of $geoNear, use the $geoNear stage with the $limit stage.要限制$geoNear的结果,请将$geoNear阶段与$limit阶段一起使用。

The following example uses the option minDistance to specify the minimum distance from the center point that the documents can be. 下面的示例使用选项minDistance指定文档与中心点的最小距离。The following aggregation finds all documents with a location at least 2 meters from the center [ -73.99279 , 40.719296 ] and category equal to Parks.以下聚合查找距离中心[ -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
     }
   }
])

$geoNear with the let option$geoNearlet选项

In this example:在这个例子中:

  • The let option is used to set an array value of [-73.99279,40.719296] to the variable $pt.let选项用于将数组值[-73.99279,40.719296]设置为变量$pt
  • $pt is specified as a let option to the near parameter in the $geoNear stage.指定为$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 ] }
}
)

The aggregation returns all documents with:聚合返回包含以下内容的所有文档:

  • A location at most 2 meters from the point defined in the let variable距离let变量中定义的点最多2米的位置
  • A category equal to Parks.等同于Parkscategory
{
   _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 ] } }
}

$geoNear with Bound let Option$geoNear带绑定let选项

The let option can bind a variable which can be used in a $geoNear query.let选项可以绑定可以在$geoNear查询中使用的变量。

In this example, $lookup uses:在本例中,$lookup使用:

  • let to define $pt.以定义$pt
  • $geoNear in the pipeline.pipeline中的$geoNear
  • $pt to define near in the $geoNear pipeline stage.$geoNear管道阶段定义near$pt
db.places.aggregate( [
   {
      $lookup: {
         from: "places",
         let: { pt: "$location" },
         pipeline: [
            {
               $geoNear: {
                  near: "$$pt",
                  distanceField: "distance"
               }
            }
         ],
         as: "joinedField"
      }
   },
   {
      $match: { name: "Sara D. Roosevelt Park" }
   }
] );

The aggregation returns a document with:聚合返回包含以下内容的文档:

  • The 'Sara D. Roosevelt Park' document as the main document.“萨拉·D·罗斯福公园”文件作为主要文件。
  • Every document in the places collection as subDocuments using the $pt variable for calculating distance.places集合中的每个文档都作为子文档使用$pt变量计算距离。
{
   _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
         }
      ]
}

Specify Which Geospatial Index to Use指定要使用的地理空间索引

New in version 4.0.在版本4.0中新增

Consider a places collection that has a 2dsphere index on the location field and a 2d index on the legacy field.考虑一个places集合,该集合在location字段上具有2dsphere索引,在legacy字段上具有2d索引。

A document in the places collection resembles the following:places集合中的文档类似于:

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

The following example uses the key option to specify that the aggregation should use the location field values for the $geoNear operation rather than the legacy field values. 以下示例使用key选项指定聚合应使用$geoNear操作的location字段值,而不是传统字段值。The pipeline also uses $limit to return at most 5 documents.管道还使用$limit返回最多5个文档。

Note注意

Starting in version 4.2, MongoDB removes the limit and num options for the $geoNear stage as well as the default limit of 100 documents. 从版本4.2开始,MongoDB删除了$geoNear阶段的limitnum选项以及100个文档的默认限制。To limit the results of $geoNear, use the $geoNear stage with the $limit stage.要限制$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 }
])

The aggregation returns the following:聚合返回以下内容:

{
   "_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 (aggregation)$graphLookup (aggregation) →