MongoDB有support for spatial indexes built-in,所以你只需要使用正确的格式加载你的点,创建空间索引,然后运行你的查询。
对于一个简单的例子,我加载的中心点为所有50个州中蒙戈壳:
> db.places.ensureIndex({loc: "2d"})
> db.places.save({name: "AK", loc: {long: -152.2683, lat: 61.3850}})
> db.places.save({name: "AL", loc: {long: -86.8073, lat: 32.7990}})
> db.places.save({name: "AR", loc: {long: -92.3809, lat: 34.9513}})
> db.places.save({name: "AS", loc: {long: -170.7197, lat: 14.2417}})
> ...
接着,对于6最近点查询给定位置:
> db.places.find({loc: { $near: {long: -90, lat: 50}}}).limit(6)
{"name" : "WI", "loc" : { "long" : -89.6385, "lat" : 44.2563 } }
{"name" : "MN", "loc" : { "long" : -93.9196, "lat" : 45.7326 } }
{"name" : "MI", "loc" : { "long" : -84.5603, "lat" : 43.3504 } }
{"name" : "IA", "loc" : { "long" : -93.214, "lat" : 42.0046 } }
{"name" : "IL", "loc" : { "long" : -89.0022, "lat" : 40.3363 } }
{"name" : "ND", "loc" : { "long" : -99.793, "lat" : 47.5362 } }
接下来,要查询给定位置10公里内的所有点。由于我计算最近的状态,我将使用888公里(这大约是8度纬度):
> db.places.find({loc: { $near: {long: -90, lat: 50}, $maxDistance: 8}})
{"name" : "WI", "loc" : { "long" : -89.6385, "lat" : 44.2563 } }
{"name" : "MN", "loc" : { "long" : -93.9196, "lat" : 45.7326 } }
由于one degree of latitude is approximately 111.12km,你会使用一个$maxDistance: 0.08999
表示10公里您的应用程序。
更新默认情况下,MongoDB采用“理想化的平坦地球模型”,但这会导致不准确,因为经线会聚在两极。 MongoDB versions 1.7+ support spherical distance calculations,它提供了更高的精度。
以下是使用球面距离运行上述查询的示例。该maxDistance
是弧度,所以我们需要在地球的平均半径来划分:
> db.runCommand({geoNear: "places", near: [-90, 50], spherical: true,
maxDistance: 800/6378});
(summarizing results as they're too verbose to include)
"MN" dis: 0.087..
"WI" dis: 0.100..
"ND" dis: 0.120..
+1。使用具有空间扩展名的数据库要容易得多。有[MySQL中的空间扩展](http://dev.mysql.com/doc/refman/5.6/en/spatial-extensions.html),另请参见[here](http://stackoverflow.com/questions/1006654 /最快的距离查对给定纬度 - 经度)。 – MarkJ 2011-05-17 11:46:59
'$ maxDistance'的单位是什么?关于这个答案有一个很大的几何球形几何气味......它似乎没有考虑到这样一个事实:**经度**在赤道上约111公里,在**处减少到** ZERO **公里极。 – 2011-05-19 03:13:19
我的例子只是为了证明存在Mongo空间扩展。我提供的链接显示了如何使用平面或球面距离功能(取决于所用软件的版本)。 – samplebias 2011-05-19 03:28:05