1. 程式人生 > >如何在thinkPHP5中使用mongoDB中空間搜尋進行位置範圍查詢

如何在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是查詢指定半徑範圍內的目標。