$geoNear
根据指定的点按照距离以由近到远的顺序输出文档。
从4.2版本开始,MongoDB移除了limit
和num
选项以及100个文档的限制,如果要限制结果文档的数量可以使用$limit
阶段。
语法
{ $geoNear: { geoNear options> } }
$geoNear
操作接受一个包含了下面选项字段的文档。使用与已处理文档坐标系相同的单位指定所有距离:
|字段|类型|描述|
|-|-|
|distanceField
|string|包含计算距离的输出字段,要指定内嵌文档字段可以使用点号.
|
|distanceMultiplier
|number|可选,查询返回的所有距离的乘数。例如,使用distanceMultiplier
将球面查询返回的弧度乘以地球半径转换为公里|
|includeLocs
|string|可选,指定识别位置的输出字段,用于计算距离。当位置字段包含多个位置时,该选项非常有用。要指定嵌入文档中的字段,可使用点符号.
|
|key
||可选,指定用于计算距离的地理空间索引字段。如果集合有多个2d
或(且)2dsphere
索引,就必须要使用key
选项来指定要使用的索引字段路径。如果集合有超过一个的2d
索引或2dsphere
索引,而且没有指定一个给key
,MongoDB将返回错误。如果没有指定key
,而且集合只有一个2d
索引或(且)2dsphere
索引,MongoDB会找到第一个2d
索引来使用,如果2d
索引不存在,则会去找2dsphere
索引来使用|
|maxDistance
|number|可选,文档与中心点的最大距离。MongoDB 会将结果限制在与中心点的距离在指定范围内的文档。如果指定点是GeoJSON,则以米为单位指定距离;如果指定点是legacy坐标对,则以弧度为单位指定距离|
|near
|GeoJSON点或legacy坐标对|查找最接近文件的点。如果使用2dsphere
索引,可以使用GeoJSON点或legacy坐标对来指定点。如果使用2d
索引,则要使用legacy坐标对来指定|
|query
|document|可选,将结果限制为与查询匹配的文档。查询语法为常规MongoDB读操作查询语法。不能在$geoNear
阶段的查询字段中指定$near
谓词|
|spherical
|boolean|可选,缺省为fasle
,决定MongoDB如何计算两点间的距离。当为true
是,MongoDB使用$nearSphere
语义并且使用球形几何体计算距离。当为false
时MongoDB 使用$near
语义:球形几何用于2dsphere
索引,平面几何用于2d
索引|
使用
当使用$geoNear
时需要考虑下面的情况:
-
$geoNear
只能用于管道的第一个阶段。 - 必须包含
distanceField
选项,distanceField
选项指定了包含距离计算的字段。 -
$geoNear
需要一个地理空间索引。如果集合上有多个地理空间索引,需要使用keys
参数指定一下计算时要使用的索引,如果只有一个地理空间索引,可以不指定keys
参数,$geoNear
会隐式使用索引字段进行计算。 -
$geoNear
阶段不可以在query
字段中使用$near
。 - 从版本4.2开始,
$geoNear
默认情况下不再限制100个文档。 - 从版本4.1开始,
near
参数支持let
选项和绑定let
选项。 - 从版本5.3开始,可以在时间序列集合的任何字段上使用
$geoNear
管道运算符。 - 从版本6.0开始,可以在时间序列集合的任何字段上创建partial和2dsphere索引。
举例
给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.95399316服务器托管网76365992,
"location" : {
"type" : "Point",
"coordinates" : [ -73.9928, 40.7193 ]
}
}
}
匹配的文档包含两个新字段:
-
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
}
}
])
使用let
选项
在下面的例子中:
-
let
选项用于将数组[-73.99279,40.719296]
的值设置给变量$pt
。 -
pt
被指定为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
选项
let
选项可以绑定一个变量用于$geoNear
查询。
在下面的例子中,$lookup
:
- 使用
let
定义$pt
。 - 在
pipeline
使用$geoNear
阶段。 - 在
$geoNear
阶段用pt
定义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
选项,为$geoNear
聚合操作指定使用location
字段的值而不是使用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
}
}
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
WXML(WeiXin Markup Language)是框架设计的一套标签语言,可以与各种组件相结合,进行页面构建。 一 常用标签 wxml的语法结构与我们熟悉的html很像,但在细节处略有不同,我们可以参考html标签对比记忆。wxml中最经常使用的标签无…