MongoDB的地理位置搜索GeoSearch使用方法探索

来源:互联网 发布:深圳小拨网络 skype 编辑:程序博客网 时间:2024/05/01 08:13

    • mongoDB的GeoSearch
    • geohash算法
    • mongoDB使用方法
      • 建立索引
      • geo查询
        • 方法一网上互相copy的方法
        • 方法二官方文档的方法
        • 方法三within方法

mongoDB的GeoSearch

 诸如陌陌,Wechat等附近的人功能,都是基于终端上传数据到服务器,然后服务器对以某一个位置为圆心,以一定范围进行搜索来实现的。
 如果我们自己对地理位置坐标进行建模搜索附近的人,需要实现GEO算法,该算法实际上是一种计算LSB地理位置距离的算法,我们最常用的一种GEO算法叫做Geohash算法,网上有许多有关这个算法的教程,我找到一部分资料,简单贴在这。

geohash算法

 wiki百科中有关geohash算法的介绍:
https://en.wikipedia.org/wiki/Geohash
其大概意思就是,将一个位置的经纬度信息,转换成一个可以排序,可以比较的字符串编码。然后,基于这个编码,就可以搜索到附近的人啦。
实现这个算法的一个git:
https://github.com/CloudSide/geohash

mongoDB使用方法

 先看以下我的collection结构:

{ "_id" : ObjectId("5a3a2803f87e0c233a5696b4"), "uid" : "34467055", "vts" : NumberLong("1513575982745"), "location" : [ 130.2619623, 31.7297297 ] }{ "_id" : ObjectId("5a3a2815f87e0c233a56b4ba"), "uid" : "30934976", "vts" : NumberLong("1513577376197"), "location" : [ 130.2828685, 31.8198198 ] }{ "_id" : ObjectId("5a3a2815f87e0c233a56b4da"), "uid" : "7195232", "vts" : NumberLong("1513572066676"), "location" : [ 130.2828685, 31.8198198 ] }

注:collection名为 login

建立索引

注意:一定要给地理位置信息建立一个索引
db.login.createIndex({“location”:”2d”})
索引有两种,一种是2dsphere 另一种是 2d,顾名思义,一个是球体,一个是平面。
对于地理位置跨度不大的,永不用球体差距不大,这个看具体业务情况了。

geo查询

官方文档:
https://docs.mongodb.com/manual/reference/command/geoSearch/

方法一:网上互相copy的方法

csdn blog上被互相疯狂抄袭的一种方法,使用$near查询。
可能是我格式不对,感兴趣的可以测试以下,搜索关键词:
mongodb 地理位置搜索 几乎都是同一种方法
网上互相copy的查询格式(测试失败):

    db.lbs.find(          {              loc: {                  $near:{                      $geometry:{                          type: "Point",                          coordinates: [113.323568, 23.146436]                      },                      $maxDistance: 1000                  }              }          }      )  

修改后,适应我的collection格式的查询方式(测试成功):

db.login.find({location:{"$near":[130.1,31.5],$maxDistance:1000}})

方法二:官方文档的方法

官方文档使用runCommand方法来查询,对应我的collection,应该是:

db.runCommand(   {      geoSearch: "login",      near: [130.1,31.5]    })

测试失败,提示:
{ “waitedMS” : NumberLong(0), “ok” : 0, “errmsg” : “no geoSearch index” }

方法三:$within方法

对于我的collection使用语句:

db.login.find({location:{"$within":{"$center":[[130.1,31.5],1]}}})

注:这个单位不是米,是一个经纬度的数量单位