如何在thinkPHP5中使用mongoDB中空間搜尋進行位置範圍查詢
在很多場景我們都會使用位置範圍服務,如查詢附近的單車、紅包數量等。網上已有很多關於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是查詢指定半徑範圍內的目標。