在很多场景我们都会使用位置范围服务,如查找附近的单车、红包数量等。网上已有很多关于mongoDB空间搜索的文章,由于thinkPHP的使用人还是比较多的,但还没有关于thinkPHP5中如何使用的相关文章。thinkPHP5中的查询条件已经默认拥有了near查询处理,但结果并不能满足我们的需求。今天闲来没事,对thinkPHP5中的范围查找进行了一下查找,希望可以帮助到拥有同等需求的伙伴们。
好了,下面开始进入正题。
通常类似这种查找一般使用MySQL、mongoDB等数据库进行操作。mysql可以写一个存储方法+视图来进行计算及操作,这里主要介绍的是mongoDB在thinkPHP5中的使用
首先你需要了解mongoDB的2dsphere、2d索引服务,及空间查找的基本使用语法。这里不在补充mongoDB的知识,以下讲解中也不在讲解语法的用意;
其次你的服务及程序需要支持mongoDB。
使用方法:
1、数据库的建立。结构如下:
在来一个直观的
红框内为存储的坐标信息,coordinate为核心字段,其他字段根据需求添加。
2、建立索引,为coordinate建立一个2dsphere的索引。
db.location.ensureIndex( { 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]]];
到目前为止,工作已经完成了。