基于MongoDB 2dSphere索引查找最近的点
在移动端普及的今天,LBS应用需求也越来越大。比如查找附近的人,最近的餐厅等。面对这些需求,MongoDB提供了功能完备的解决方案。下面通过一个案例来解释一下MongoDB的2dSphere
在这个图片中,有A B C D E F G,假如我是搜索点A。我想查找离自己最近的点。下面是具体的操作步骤:
建立集合和索引。sp为建立索引的字段名,我们建立的索引类型是2dsphere
1 2
| # 创建2dsphere索引 db.sphere.ensureIndex({"sp":"2dsphere"})
|
向集合中插入测试数据,我们插入的是实际的经纬度。
这里需要注意的是,如果我们如果用的是2dsphere索引,那么插入的应该是GeoJson数据。GeoJson的格式是
{ type: ‘GeoJSON type’ , coordinates: ‘coordinates’ }
其中type指的是类型,可以是Point(本例中用的),LineString,Polygon等,coordinates是一个坐标数组。英语好的同学可以去官网看看https://docs.mongodb.com/manual/reference/geojson/
1 2 3 4 5 6 7 8
| # 插入Point数据 db.sphere.insert({name:"A",sp:{type:"Point",coordinates:[105.754484701156,41.689607057699]}}) db.sphere.insert({name:"B",sp:{type:"Point",coordinates:[105.304045248031,41.783456183240]}}) db.sphere.insert({name:"C",sp:{type:"Point",coordinates:[105.084318685531,41.389027478812]}}) db.sphere.insert({name:"D",sp:{type:"Point",coordinates:[105.831388998031,41.285916385493]}}) db.sphere.insert({name:"E",sp:{type:"Point",coordinates:[106.128706502914,42.086868474465]}}) db.sphere.insert({name:"F",sp:{type:"Point",coordinates:[105.431074666976,42.009365053841]}}) db.sphere.insert({name:"G",sp:{type:"Point",coordinates:[104.705977010726,41.921549795110]}})
|
进行查询。介绍一下其中的参数
(1)geoNear:我们要查询的集合名称
(2)near:就是基于那个点进行搜索,这里是我们的搜索点A
(3)spherical:是个布尔值,如果为true,表示将计算实际的物理距离比如两点之间有多少km,若为false,则会基于点的单位进行计算
(4)minDistance:搜索的最小距离,这里的单位是米
(5)maxDistance:搜索的最大距离
1 2 3 4 5 6 7
| db.runCommand({ geoNear:"sphere", near:{type:"Point",coordinates:[105.794621276855,41.869574065014]}, spherical:true, minDistance:25000, maxDistance:40000, })
|
结果分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| { "waitedMS" : NumberLong(0), "results" : [ { "dis" : 33887.5416611258, "obj" : { "_id" : ObjectId("57e3857e6a4a326367ae0d05"), "name" : "F", "sp" : { "type" : "Point", "coordinates" : [ 105.431074666976, 42.009365053841 ] } } }, { "dis" : 36734.9748784127, "obj" : { "_id" : ObjectId("57e3857e6a4a326367ae0d04"), "name" : "E", "sp" : { "type" : "Point", "coordinates" : [ 106.128706502914, 42.086868474465 ] } } } ], "stats" : { "nscanned" : 24, "objectsLoaded" : 20, "avgDistance" : 35311.2582697693, "maxDistance" : 36734.9748784127, "time" : 87 }, "ok" : 1.0 }
|
在results中,我们搜索到了点F和E。每个文档都加上了一个dis字段,他表示这个点离你搜索点的距离。
比如说,在结果中name为F的点的dis为33887.5416611258。表示F点距离搜索点的距离是33887米。这个结果对于LBS应用是非常有用的。