MongoDB支持内置空间索引,因此您需要做的就是使用正确的格式加载您的点,创建空间索引,然后运行您的查询。
举个简单的例子,我在 mongo shell 中加载了所有 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 } }
接下来,查询给定位置 10km 内的所有点。由于我正在计算最近的州,因此我将使用 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 } }
由于一个纬度大约是111.12km,因此您可以使用 a$maxDistance: 0.08999
来表示您的应用程序的 10km。
更新默认情况下,MongoDB 假定一个“理想的平面地球模型”,但这会导致不准确,因为经度线会聚在两极。 MongoDB 1.7+ 版本支持球面距离计算,这提供了更高的精度。
这是使用球面距离运行上述查询的示例。是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..