正在官方:
mongos> db.checkins.insert({ "_id" : "101", "loc" : [ 116.3447, 39.9789 ]})
mongos> db.checkins.insert({ "_id" : "102", "loc" : [ 116.3447, 39.8789 ]})
mongos> db.checkins.insert({ "_id" : "103", "loc" : [ 116.3447, 39.5789 ]})
2.创建索引 : mongos> db.checkins.ensureIndex({loc:"2d"})
3.查找44km以内的人 mongos> db.checkins.find({loc:{$near:[116.344722,39.9789],$maxDistance:44/111.12 }})
注意距离要除以111.2(1度=111.2km),跟平常的查找的区别仅仅是多了两个算子$near和$maxDistance4.还可以利用命令geoNear来查找,还可以返回距离目标点的距离:
db.runCommand( { geoNear : "places" , near : [50,50], num : 10 } );
2dsphere
在GeoJson的基础上,为了获得更加准确的运算效果,官方推荐采用2dsphere的方式
1.创建索引:
db.places.ensureIndex( { loc : "2dsphere" } )
db.places.ensureIndex( { loc : "2dsphere" , category : -1, name: 1 } )
db.places.ensureIndex( { category : 1 , loc : "2dsphere" } )
单位解释:a.通常经纬度是基于角度还进行衡量的,范围在-180到180之间
b.如果是2d索引,所有的查询都是基于角度的,查询的时候要把距离转成角度,即除以111.1公里
c.如果是2dsphere索引,所有的查询都是基于弧度的,查询的时候要把距离转成弧度,即除以6371公里,最后再把结果转成弧度
2.查询:
对于以下几个操作和命令:
$nearSphere/$centerSphere/$near/geoNear command with the { spherical: true } option.
都是基于弧度的,在运算前和运算后要进行距离和弧度的转换
查询圆形范围:
db.places.find( { loc: { $geoWithin: { $centerSphere: [ [ -74, 40.74 ] ,
100 / 6371 ] } } } )
查询附近点:
db.runCommand( { geoNear: "places",
near: [ -74, 40.74 ],
spherical: true,
distanceMultiplier: 6371
} )
不同索引对查询操作的支持情况
| Name | Description |
|---|---|
$geoIntersects |
2dsphere支持 |
$geoWithin |
2d和2dsphere支持 |
$nearSphere |
2d和2dsphere支持 |
$near |
2d和2dsphere支持 |
不同索引对查询子的支持情况
| Name | Description |
|---|---|
| $box/$center | 2d支持,用于$geoWithin |
| $centerSphere | 2d和2dsphere支持,用于$geoWithin,后者采用GeoJson格式 |
|
2d和2dsphere支持,用于$near和$nearSphere,分别采用度和弧度 |
|
2dsphere支持,用于$near和$nearSphere,采用弧度 |
| 指定查询时的GeoJson格式 | |
| 指定查询时的多边形格式,用于$geoWithin,2d支持center |
不同的索引的对照表
| 查询文档 | 查询的几何图形 | 平面类型 | 计算的单位 | 支持的索引 |
|---|---|---|---|---|
| Returns points, lines and polygons |
|
|
|
|
{ $geoWithin : {
$geometry : <GeoJSON Polygon>
} }
|
polygon | sphere | meters | 2dsphere |
{ $geoIntersects : {
$geometry : <GeoJSON>
} }
|
point, line or polygon | sphere | meters | 2dsphere |
{ $near : {
$geometry : <GeoJSON Point>,
$maxDistance : d
} }
|
point | sphere | meters |
2dsphere |
| Returns points only |
|
|
|
|
{ $geoWithin : {
$box : [[x1, y1], [x2, y2]]
} }
|
rectangle | flat | flat units | 2d |
{ $geoWithin : {
$polygon : [[x1, y1],
[x1, y2],
[x2, y2],
[x2, y1]]
} }
|
polygon | flat | flat units | 2d |
{ $geoWithin : {
$center : [[x1, y1], r],
} }
|
circular region | flat | flat units | 2d |
{ $geoWithin : {
$centerSphere :
[[x, y], radius]
} }
|
circular region | sphere | radians |
2d 2dsphere |
{ $near : [x1, y1],
$maxDistance : d
}
|
point | flat / flat units | flat units |
2d |
a.$geoWithin
{
<location field>: {
$geoWithin: {
$geometry: {
type: <"Polygon" or "MultiPolygon"> ,
coordinates: [ <coordinates> ]
}
}
}
}
{
<location field>: {
$geoWithin: { <shape operator>: <coordinates> }
}
}
b.$nearSphere
{
$nearSphere: {
$geometry: {
type : "Point",
coordinates : [ <longitude>, <latitude> ]
},
$minDistance: <distance in meters>,
$maxDistance: <distance in meters>
}
}
{
$nearSphere: [ <x>, <y> ],
$minDistance: <distance in radians>,
$maxDistance: <distance in radians>
}
c.$near
{
$near: {
$geometry: {
type: "Point" ,
coordinates: [ <longitude> , <latitude> ]
},
$maxDistance: <distance in meters>,
$minDistance: <distance in meters>
}
}
{
$near: [ <x>, <y> ],
$maxDistance: <distance in radians>
}
d.$box
{
<location field>: {
$geoWithin: {
$box: [
[ <bottom left coordinates> ],
[ <upper right coordinates> ]
]
}
}
}
e.$center
{
<location field>: {
$geoWithin: { $center: [ [ <x>, <y> ] , <radius> ] }
}
}
f.$centerSphere
{
<location field>: {
$geoWithin: { $centerSphere: [ [ <x>, <y> ], <radius> ] }
}
}
g.$polygon
{
<location field>: {
$geoWithin: {
$polygon: [ [ <x1> , <y1> ], [ <x2> , <y2> ], [ <x3> , <y3> ], ... ]
}
}
}
3.命令
| 字段 | 类型 | 描述 |
|---|---|---|
geoNear |
string | 命令名. |
near |
GeoJSON或坐标对 |
指定附近点的坐标 对于2dsphere用GeoJson,对于2s用坐标对 |
spherical |
Boolean |
是否用球面来计算距离,如果是2dsphere必须为true |
limit |
number | 返回的最大数,默认是100 |
num |
number | 同上,如果同时出现,会覆盖上面的. |
minDistance |
number |
限制的最小距离,如果是GeomJson单位为米,如果是坐标对单位为弧度 |
maxDistance |
number | 限制的最大距离,如果是GeomJson单位为米,如果是坐标对单位为弧度 |
query |
document |
额外的查询条件 |
distanceMultiplier |
number | 对返回的基于距离的结果,乘以这个算子 |