如何在thinkPHP5中使用mongoDB中空间搜索进行位置范围查找

来源:互联网 发布:plsql怎么执行sql文件 编辑:程序博客网 时间:2024/06/05 11:02

在很多场景我们都会使用位置范围服务,如查找附近的单车、红包数量等。网上已有很多关于mongoDB空间搜索的文章,由于thinkPHP的使用人还是比较多的,但还没有关于thinkPHP5中如何使用的相关文章。thinkPHP5中的查询条件已经默认拥有了near查询处理,但结果并不能满足我们的需求。今天闲来没事,对thinkPHP5中的范围查找进行了一下查找,希望可以帮助到拥有同等需求的伙伴们。


好了,下面开始进入正题。


通常类似这种查找一般使用MySQL、mongoDB等数据库进行操作。mysql可以写一个存储方法+视图来进行计算及操作,这里主要介绍的是mongoDB在thinkPHP5中的使用,如果需要了解mysql处理的可以私信我。


首先你需要了解mongoDB的2dsphere、2d索引服务,及空间查找的基本使用语法。这里不在补充mongoDB的知识,以下讲解中也不在讲解语法的用意;

其次你的服务及程序需要支持mongoDB。


使用方法:

1、数据库的建立。结构如下:


在来一个直观的



红框内为存储的坐标信息,coordinate为核心字段,其他字段根据需求添加。


2、建立索引

db.location.ensureIndex( { coordinate : "2dsphere" } )  
为coordinate建立一个2dsphere的索引。


3、PHP代码书写


db_mongo为我的mongodb配置。

where条件解释:

['coordinate' => ['near',[$get['lat'],$get['lng'],5000]]]

coordinate 查询字段

near 查询语法,类似in like等

$get['lat']  中心点lat

$get['lng'] 中心点lng

5000 查询最大范围,单位米


由于thinkPHP5的mongo操作中没有支持geo within的语法以及near不符合我们的预期,我们需要对其进行增加及修改,(不愿意修改near的可以在增加一个自定义的语法)。


修改方式:

找到mongodb的操作,我的文件路径是:



然后找到parseWhereItem方法。在里面的查询语法判断中进行一个增加及修改操作,具体请看图:



蓝色为修改部分,红色为增加部分。

上图示例中


coordinates名字我都是写固定的,如果你需要不固定的,请自己在多传一个数据来代替。


为了方便复制,以下为代码

//空间点距查询$query[$key] = (object)['$near' => (object)['$geometry' => (object)['type'=>'Point','coordinates' => [$value[0],$value[1]]],'$maxDistance' => $value[2]]];//半径范围查询  #指定一个半径,查找半径内的数据,不按距离排序$query[$key] = (object)['$geoWithin' => (object)['$centerSphere' => [[$value[0],$value[1]],$value[2]/6370.996]]];

到目前为止,工作已经完成了。

现在来看一下效果:



注意:后面的距离我是通过百度地图的结果进行计算的,由此得出结论。mongodb的$near查询出来的结果排序(从近到远)和百度地图的一致。

这里演示的是near语法范围内查找并按距离由近到远排序。geo within使用方法与near一致,只需要在查询条件中把查询参数由near换成geo within即可。geo within是查询指定半径范围内的目标。