Database Manual / Reference / Query Language / Aggregation Stages

$geoNear (aggregation stage)(聚合阶段)

Definition定义

$geoNear

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

Note

MongoDB removes the limit and num options for the $geoNear stage as well as the default limit of 100 documents. MongoDB删除了$geoNear阶段的limitnum选项,以及100个文档的默认限制。To limit the results of $geoNear, use the $geoNear stage with the $limit stage.要限制$geoNear的结果,请将$geoNears阶段与$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运算符接受包含以下$geoNears选项的文档。Specify all distances in the same units as those of the processed documents' coordinate system:以与已处理文档坐标系相同的单位指定所有距离:

Field字段Type类型Description描述
distanceFieldstring字符串

The output field that contains the calculated distance. To specify a field within an embedded document, use dot notation.包含计算距离的输出字段。要在嵌入式文档中指定字段,请使用点符号

This field is required for queries on timeseries collections. Starting in MongoDB 8.1, distanceField is optional for queries on non-timeseries collections.此字段是查询时间序列集合所必需的。从MongoDB 8.1开始,distanceField对于非时间序列集合的查询是可选的。

distanceMultipliernumber数字Optional. 可选。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将球面查询返回的弧度乘以地球半径,转换为公里。
includeLocsstring字符串Optional. 可选。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索引,并且您没有指定键,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索引。

maxDistancenumber数字

Optional. 可选。The maximum distance from the center point that the documents can be. 文档离中心点的最大距离。MongoDB limits the results to those documents that fall within the specified distance from the center point. Starting in version 7.2, you can specify a valid constant expression that resolves to a number.MongoDB将结果限制在距离中心点指定距离内的文档中。从7.2版本开始,您可以指定一个解析为数字的有效常量表达式

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 can be. MongoDB limits the results to those documents that fall outside the specified distance from the center point. 文档离中心点的最小距离。MongoDB将结果限制在离中心点指定距离之外的文档中。Starting in version 7.2, you can specify a valid constant expression that resolves to a number.从7.2版本开始,您可以指定一个解析为数字的有效常量表达式

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.当为真时,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.

Behavior行为

Distance Calculations距离计算

$geoNear calculates distance based on the nearest point of the input document's perimeter.根据输入文档周长的最近点计算距离。

For example, if the input document is a shape, $geoNear identifies the point on the shape's perimeter that is nearest to the specified point and outputs the distance between the specified point and the shape's nearest point.例如,如果输入文档是一个形状,$geoNear会标识形状周长上最接近指定点的点,并输出指定点与形状最近点之间的距离。

Considerations注意事项

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

  • You can only use $geoNear as the first stage of a pipeline.您只能将$geoNear用作管道的第一阶段。
  • $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会隐式使用索引字段进行计算。

Examples示例

MongoDB Shell

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:以下操作在location字段上创建2dsphere索引:

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

Maximum Distance最大距离

Note

MongoDB removes the limit and num options for the $geoNear stage as well as the default limit of 100 documents. MongoDB删除了$geoNear阶段的limitnum选项,以及100个文档的默认限制。To limit the results of $geoNear, use the $geoNear stage with the $limit stage.要限制$geoNear的结果,请将$geoNears阶段与$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查找位置距离中心最多2米的文档[ -73.99279 , 40.719296 ]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

MongoDB removes the limit and num options for the $geoNear stage as well as the default limit of 100 documents. MongoDB删除了$geoNear阶段的limitnum选项,以及100个文档的默认限制。To limit the results of $geoNear, use the $geoNear stage with the $limit stage.要限制$geoNear的结果,请将$geoNears阶段与$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选项用于为变量$pt设置数组值[-73.99279,40.719296]
  • $pt is specified as a let option to the near parameter in the $geoNear stage.$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 ] }
}
)

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.一个与Parks相等的category
{
_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中。
  • $pt to define near in the $geoNear pipeline stage.$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" }
}
] );

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指定要使用的地理空间索引

Consider a places collection that has a 2dsphere index on the location field and a 2d index on the legacy field.考虑一个places集合,它在位置字段上有一个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字段值,而不是legacy字段值。The pipeline also uses $limit to return at most 5 documents.该管道还使用$limit最多返回5个文档。

Note

MongoDB removes the limit and num options for the $geoNear stage as well as the default limit of 100 documents. MongoDB删除了$geoNear阶段的limitnum选项,以及100个文档的默认限制。To limit the results of $geoNear, use the $geoNear stage with the $limit stage.要限制$geoNear的结果,请将$geoNears阶段与$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
}
}
C#

The C# examples on this page use the sample_mflix.theaters collection from the Atlas sample datasets. 本页上的C#示例使用Atlas示例数据集中的sample_mflix.theaters集合。To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see Get Started in the MongoDB .NET/C# Driver documentation.要了解如何创建免费的MongoDB Atlas集群并加载示例数据集,请参阅MongoDB NET/C#驱动程序文档中的入门

The following Theater, Location, and Address classes model the documents in the sample_mflix.theaters collection:以下TheaterLocationAddress类对sample_mflix.theaters集合中的文档进行建模:

public class Theater
{
public ObjectId Id { get; set; }

[BsonElement("theaterId")]
public int TheaterId { get; set; }

[BsonElement("location")]
public Location Location { get; set; }

[BsonElement("distance")]
public double? Distance { get; set; }
}

public class Location
{
[BsonElement("address")]
public Address Address { get; set; }

[BsonElement("geo")]
public GeoJsonPoint<GeoJson2DGeographicCoordinates> Geo { get; set; }
}

[BsonIgnoreExtraElements]
public class Address
{
[BsonElement("city")]
public string City { get; set; }

[BsonElement("state")]
public string State { get; set; }
}

To use the MongoDB .NET/C# driver to add a $geoNear stage to an aggregation pipeline, call the GeoNear() method on a PipelineDefinition object.要使用MongoDB NET/C#驱动程序将$geoNear阶段添加到聚合管道中,请在PipelineDefinition对象上调用geoNear()方法。

This method is available only in MongoDB .NET/C# driver v3.4 and later.此方法仅在MongoDB .NET/C#驱动程序v3.4及更高版本中可用。

Maximum Distance最大距离

The following example creates a pipeline stage that returns documents in an 8000 meter radius of the specified point, in order of ascending distance. 以下示例创建了一个管道阶段,该阶段按距离升序返回指定点8000米半径内的文档。The code includes a Query parameter that only matches documents in which the value of the location.address.state field is "NJ". The code also stores the calculated distance in the distance field of the output documents.该代码包含一个Query参数,该参数仅匹配location.address.state字段值为"NJ"的文档。该代码还将计算出的距离存储在输出文档的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"),
});

Minimum Distance最小距离

The following example returns the first 4 matching documents outside of an 8000 meter radius of the specified point, in order of ascending distance. 以下示例按距离升序返回指定点8000米半径外的前4个匹配文档。The code includes a Query parameter that only matches documents in which the value of the location.address.state field is "NJ". 该代码包含一个Query参数,该参数仅匹配location.address.state字段值为"NJ"的文档。The code also stores the calculated distance in the distance field of the output documents.该代码还将计算出的距离存储在输出文档的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

The Node.js examples on this page use the sample_mflix database from the Atlas sample datasets. 本页上的Node.js示例使用Atlas示例数据集中的sample_mflix数据库。To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see Get Started in the MongoDB Node.js driver documentation.要了解如何创建免费的MongoDB Atlas集群并加载示例数据集,请参阅MongoDB Node.js驱动程序文档中的入门

To use the MongoDB Node.js driver to add a $geoNear stage to an aggregation pipeline, use the $geoNear operator in a pipeline object.要使用MongoDB Node.js驱动程序将$geoNear阶段添加到聚合管道中,请在管道对象中使用$geoNear运算符。

Maximum Distance最大距离

The following example creates a pipeline stage that returns documents in an 8000 meter radius of the specified point, in order of ascending distance. 以下示例创建了一个管道阶段,该阶段按距离升序返回指定点8000米半径内的文档。The code includes a query field that only matches documents where the value of the location.address.state field is "NJ". 该代码包含一个查询字段,该字段仅匹配location.address.state字段值为"NJ"的文档。The code also stores the calculated distance in the distance field of the output documents. The example then runs the aggregation pipeline:该代码还将计算出的距离存储在输出文档的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;

Minimum Distance最小距离

The following example returns the first 4 matching documents outside of an 8000 meter radius of the specified point, in order of ascending distance. 以下示例按距离升序返回指定点8000米半径外的前4个匹配文档。The code includes a query field that only matches documents where the value of the location.address.state field is "NJ". 该代码包含一个query字段,该字段仅匹配location.address.state字段值为"NJ"的文档。The code also stores the calculated distance in the distance field of the output documents:该代码还将计算出的距离存储在输出文档的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;

Learn More了解更多

To learn more about related pipeline stages, see the $limit guide.要了解有关相关管道阶段的更多信息,请参阅$limit指南。