Definition定义
$geoNearOutputs documents in order of nearest to farthest from a specified point.按离指定点最近到最远的顺序输出文档。Note
The$geoNearstage has the following prototype form:$geoNear阶段具有以下原型形式:{ $geoNear: { <geoNear options> } }The$geoNearoperator accepts a document that contains the following$geoNearoptions.$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,此字段是查询时间序列集合所必需的。从MongoDB 8.1开始,distanceFieldis optional for queries on non-timeseries collections.distanceField对于非时间序列集合的查询是可选的。distanceMultipliernumber数字Optional.可选。The factor to multiply all distances returned by the query.将查询返回的所有距离相乘的因子。For example, use the例如,使用distanceMultiplierto 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.要在嵌入式文档中指定字段,请使用点符号。keyOptional.可选。Specify the geospatial indexed field to use when calculating the distance.指定计算距离时要使用的地理空间索引字段。If your collection has multiple如果您的集合有多个2dand/or multiple2dsphereindexes, you must use thekeyoption 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如果有多个2dindex or more than one2dsphereindex and you do not specify akey, MongoDB will return an error.2d索引或多个2dsphere索引,并且您没有指定键,MongoDB将返回错误。If you do not specify the如果不指定key, and you have at most only one2dindex and/or only one2dsphereindex, MongoDB looks first for a2dindex to use.key,并且最多只有一个2d索引和/或一个2dsphere索引,MongoDB会首先查找要使用的2d索引。If a如果2dindex does not exists, then MongoDB looks for a2dsphereindex 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您不能在$nearpredicate in thequeryfield of the$geoNearstage.$geoNear阶段的query字段中指定$near谓词。sphericalboolean布尔值Optional.可选。Determines how MongoDB calculates the distance between two points:确定MongoDB如何计算两点之间的距离:When当为真时,MongoDB使用true, MongoDB uses$nearSpheresemantics and calculates distances using spherical geometry.$nearSphere语义,并使用球面几何计算距离。When当为false, MongoDB uses$nearsemantics: 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您只能将$geoNearas the first stage of a pipeline.$geoNear用作管道的第一阶段。$geoNearrequires a geospatial index.需要地理空间索引。If you have more than one geospatial index on the collection, use the如果集合上有多个地理空间索引,请使用keysparameter to specify which field to use in the calculation.keys参数指定在计算中使用哪个字段。If you have only one geospatial index,如果只有一个地理空间索引,$geoNearimplicitly uses the indexed field for the calculation.$geoNear会隐式使用索引字段进行计算。
You cannot specify a您不能在$nearpredicate in thequeryfield of the$geoNearstage.$geoNear阶段的查询字段中指定$near谓词。$geoNearno longer has a default limit of 100 documents.不再有100个文档的默认限制。Starting in MongoDB 5.1, the从MongoDB 5.1开始,nearparameter supports the let option and bound let option.near参数支持let选项和绑定let选项。Starting in MongoDB 5.3, you can use the从MongoDB 5.3开始,您可以在时间序列集合中的任何字段上使用$geoNearpipeline operator on any field in a time series collection.$geoNear管道运算符。Starting in MongoDB 6.0, you can create partial and 2dsphere indexes on any field in a time series collection.从MongoDB 6.0开始,您可以在时间序列集合中的任何字段上创建partial索引和2dsphere索引。Starting in MongoDB 8.0,从MongoDB 8.0开始,$near,$nearSphere, and$geoNearvalidate that the type of the specified GeoJSON points isPoint. Any other input type returns an error.$near、$nearSphere和$geoNear验证指定的GeoJSON点的类型是否为Point。任何其他输入类型都会返回错误。
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
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.calculatedfield that contains the calculated distance, and包含计算距离的字段,以及dist.locationfield that contains the location used in the calculation.包含计算中使用的位置的字段。
Minimum Distance最小距离
Note
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$geoNear带let选项
let optionIn this example:在这个例子中:
Theletoption is used to set an array value of[-73.99279,40.719296]to the variable$pt.let选项用于为变量$pt设置数组值[-73.99279,40.719296]。$ptis specified as aletoption to thenearparameter in the$geoNearstage.$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距离letvariablelet变量中定义的点最多2米的位置A一个与categoryequal toParks.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选项
let OptionThe let option can bind a variable which can be used in a $geoNear query.let选项可以绑定一个可用于$geoNear查询的变量。
In this example, 在此示例中,$lookup uses:$lookup使用:
letto define用来定义$pt.$pt。$geoNearin the在pipeline.pipeline中。$ptto definenearin the$geoNearpipeline 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 theplacescollection as subDocuments using the$ptvariable 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
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 本页上的C#示例使用Atlas示例数据集中的sample_mflix.theaters collection from the Atlas sample datasets. 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: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; }
}
To use the MongoDB .NET/C# driver to add a 要使用MongoDB NET/C#驱动程序将$geoNear stage to an aggregation pipeline, call the GeoNear() method on a PipelineDefinition object.$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 本页上的Node.js示例使用Atlas示例数据集中的sample_mflix database from the Atlas sample datasets. 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 要使用MongoDB Node.js驱动程序将$geoNear stage to an aggregation pipeline, use the $geoNear operator in a pipeline object.$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指南。