Docs 菜单
Docs 主页
/
MongoDB Manual
/ / /

$geoNear(聚合)

在此页面上

  • 定义
  • 行为
  • 示例
$geoNear

按距离指定点最近到最远的顺序输出文档。

注意

MongoDB 删除了 $geoNear 阶段的 limitnum 选项以及 100 个文档的默认限制。要限制 $geoNear 的结果,可以使用 $geoNear 阶段和 $limit 阶段。

$geoNear 阶段具有以下原型形式:

{ $geoNear: { <geoNear options> } }

$geoNear 运算符接受包含以下 $geoNear 选项的文档。使用与已处理文档坐标系相同的单位指定所有距离:

字段
类型
说明
distanceField
字符串
包含计算出的距离的输出字段。要在嵌入式文档中指定字段,请使用点符号
distanceMultiplier
数字
可选。用于与查询返回的所有距离相乘的系数。例如,使用 distanceMultiplier 乘以地球半径,将球形查询返回的弧度转换为公里。
includeLocs
字符串
可选。这指定了一个输出字段,用于标识用来计算距离的位置。该选项适合位置字段包含多个位置的情况。要在嵌入式文档中指定字段,请使用点符号
key

可选。指定计算距离时使用的地理空间索引字段。

如果您的集合有多个 2d 和/或多个 2dsphere 索引,则必须使用 key 选项来指定要使用的带索引字段路径。“指定要使用的地理空间索引”中提供了一个完整示例。

如果存在多个 2d 索引或多个 2dsphere 索引,并且您未指定 key,MongoDB 将返回错误。

如果未指定 key,并且您最多只有一个 2d 索引和/或只有一个 2dsphere 索引,MongoDB 首先会查找要使用的 2d 索引。如果 2d 索引不存在,则 MongoDB 会查找要使用的 2dsphere 索引。

maxDistance
数字

可选。 文档与中心点相距的最大距离。 MongoDB 将结果限制为与中心点相距指定距离内的文档。 从版本 7.2 开始,您可以指定解析为数字的有效常量表达式

如果指定点为 GeoJSON,则以米为单位指定距离;如果指定点是传统坐标对,则以弧度为单位指定距离。

minDistance
数字

可选。 文档与中心点的最小距离。 MongoDB 将结果限制为与中心点相距指定距离之外的文档。 从版本 7.2 开始,您可以指定解析为数字的有效常量表达式

对于 GeoJSON 数据,以米为单位指定距离;对于传统坐标对,以弧度为单位指定距离。

near
GeoJSON 点或传统坐标对

查找最新文档的点。

如果使用 2dsphere 索引,则可以将该点指定为 GeoJSON 点或传统坐标对。

如果使用 2d 索引,请将该点指定为传统坐标对。

query
文档

可选。将结果限制为与查询匹配的文档。查询语法是通常的 MongoDB 读取操作查询语法。

不能在 $geoNear 阶段的 query 字段中指定 $near 谓词。

spherical
布尔

可选。确定 MongoDB 如何计算两点之间的距离:

  • true 时,MongoDB 使用 $nearSphere 语义,并使用球面几何计算距离。

  • false 时,MongoDB 使用 $near 语义:2dsphere 索引用于球面,2d 索引用于平面。

默认值:false。

在使用 $geoNear 时,请考虑:

  • 只能使用 $geoNear 作为管道的第一阶段。

  • 必须包含 distanceField 选项。distanceField 选项指定包含计算出的距离的字段。

  • $geoNear 需要地理空间索引。

    如果集合上有多个地理空间索引,请使用 keys 参数指定要在计算中使用的字段。如果你只有一个地理空间索引,$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 阶段的 limitnum 选项以及 100 个文档的默认限制。要限制 $geoNear 的结果,可以使用 $geoNear 阶段和 $limit 阶段。

上面的 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 ]
}
}
}

匹配文档包含两个新字段:

  • dist.calculated 字段,其包含计算出的距离,以及

  • dist.location 字段,包含计算中使用的位置。

注意

MongoDB 移除了 $geoNear 阶段的 limitnum 选项以及 100 个文档的默认限制。要限制 $geoNear 的结果,可以使用 $geoNear 阶段和 $limit 阶段。

以下示例使用选项 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
}
}
])

在本例中:

  • 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 米的位置

  • 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 ] } }
}

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 变量将地点集合中的每个文档作为子文档来计算距离。

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

考虑 places 集合,它在 location 字段上有 2dsphere 索引,在 legacy 字段上有 2d 索引。

places 集合中的文档类似于以下内容:

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

以下示例使用了 key 选项,具体指定聚合应使用 location 字段值来执行 $geoNear 操作,而不是使用 legacy 字段值。该管道还使用了 $limit,最多返回 5 个文档。

注意

MongoDB 移除了 $geoNear 阶段的 limitnum 选项以及 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

在此页面上