正在官方:
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和$maxDistance
4.還可以利用命令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 | 對返回的基於距離的結果,乘以這個算子 |