LBS(Location Based Services)定位服務,即根據用戶位置查詢用戶附近相關信息,這一功能在很多應用上都有所使用。基於用戶位置進行查詢時,需要提供用戶位置的經緯度。為了提高查詢速度,MongoDB為坐標平面查詢提供了專門的索引,稱作地理空間(2d)索引。
1. 創建地理空間索引
地理空間索引又稱為2d索引。創建其它形式的索引,我們會按升序或降序(1或-1)的形式創建索引,不同於其它形式的索引,創建地理空間索引要指定的值為:2d。語法結構如下:
db.<collection>.createIndex({ <location field> : "2d" , <additional field> : <value> } , { <index-specification options>})
location field:要創建地理空間索引的字段(鍵)
additional field:附加字段(鍵)
index-specification options:索引選項
index-specification options是一個包含以下可選值的子文檔:
{ min : <lower bound>, max : <upper bound>, bits : <bit precision> }
min bound:{number},最低范圍,默認-180.0
max bound:{number},最高范圍,默認180.0
bit precision:{integer},存儲數據Geohash值精度,取值:1〜32,默認26
地理空間計算本質上是二維數據計算,創建索引地理空間索引時,索引鍵的值必須是一對值:一個包含兩個數值的數組或包含兩個鍵的內嵌文檔(內嵌文檔鍵的名稱不重要)。
以下幾種健值形式,都可以創建地理空間索引:
// 數組 {"gps": [40, 120]} // 包含兩個鍵的內嵌文檔 {"gps": { "x":40, "y":120}} {"gps": { "latitude":40, "longitude":120}}
我們可以對上面的"gps"健創建地理空間索引:
db.userlocation.ensureIndex({"gps" : "2d"}, {"min":-1000, "max":1000});
這樣我們就創建了地理空間索引值范圍為-1000〜1000的索引。
2. 使用地理空間索引查詢
2.1 $near接近點查詢
通過$near關鍵字,可以根據一個指定的平面點,按距離排序返回查詢結果:
db.<collection>.find({ <location field> :{ $near : [ <x>, <y>], $maxDistance : <distance in meters<, $mixDistance : <distance in meters< } })
$near表示要查詢的中心點
$maxDistance距中心點的最大距離
$minDistance距中心點的最小距離
如,查詢距離坐標點(40,120),10公里以內的數據:
db.userlocation.find({ gps : { $near : [40, 120], $maxDistance : 10 } })
2.2 $geoWithin指定形狀查詢
MongoDB不僅可以按坐標點查詢,還可以在查詢指定形狀內的文檔。按形狀查詢使用$geoWithin(在v2.4之前使用$within):
db.<collection<.find({ <location field> :{ $geoWithin : { $box|$polygon|$center : <coordinates>} } })
在指定形狀查詢中,$box、$polygon、$center分別表示按矩形、五邊形、圓形進行查詢。
如,查詢坐標點為(40,120),半徑為10以內的文檔:
db.userlocation.find({ gps : { $geoWithin : { $center:[[40, 120], 10] } } })