地圖距離排序一(mongodb篇)

在使用外賣或團購 App 篩選商家時,我們經常會用到一個功能,叫作按照離我最近排序。在使用共享單車時,App 會自動幫我們搜索出,距離我們最近幾公里內的單車。那麼這兩種場景,在服務端要如何實現呢?今天我們將使用 mongodb 來實現這兩種場景。

首先我們準備數據集,創建一個 location 庫,然後插入一些數據。如下:

例:db.location.insert({"lng":經度,"lat":緯度,"loc":[lng,lat]});
db.location.insert({"lng":1,"lat":1,"loc":[1,1]});
db.location.insert({"lng":2,"lat":2,"loc":[2,2]});
db.location.insert({"lng":3,"lat":3,"loc":[3,3]});
db.location.insert({"lng":-1,"lat":-1,"loc":[-1,-1]});
db.location.insert({"lng":-2,"lat":-2,"loc":[-2,2]});   
db.location.insert({"lng":-3,"lat":-3,"loc":[-3,-3]});

數據集準備好了之後,我們需要爲 location 加上地圖索引。mongodb 提供的地圖索引有兩種,分別是 2d 和 2dsphere。2d 索引通過二維平面記錄點座標,支持在平面幾何中計算距離,而 2dsphere 則支持在球面上進行距離的計算,並且支持 mongodb 的所有地理空間查詢方法。簡單的理解,2dsphere 是 2d 的增強版。根據官方推薦,如果你的mongodb版本大於2.6,那麼就用 2dsphere 索引 。如下:

db.location.ensureIndex({"loc":"2dsphere"})

索引加好後,我們就可以來實現按照離我最近排序了,姿勢如下:

db.location.find({
    "loc":{
        "$nearSphere":{
            "$geometry":{
                "type":"Point",
                "coordinates":[0,0]
            }
        }
    }
})

按照離我最近排序,除了使用 $nearSphere 查詢外,我們還可以使用 aggregate 來實現。

使用 aggregate 有兩個好處。1.我們在進行排序的後,可以返回兩點之間的距離。2.我們可以進行更爲複雜的排序,例如我們可以先根據某個字段進行排序,然後該字段相同的情況下再根據距離排序。

使用 aggregate 查詢時,我們還可以返回兩點之間的距離,其中 distanceField 可以對距離字段進行重命名。姿勢如下:

db.location.aggregate([
   {
     $geoNear: {
        near: { type: "Point", coordinates: [ 0 , 0 ] },
        distanceField: "distance",
        spherical: true
     }  
   }
])

如果我們希望查詢以某個點爲中心的圓幾公里以內的數據,那你的姿勢可以如下:

db.location.find({
    "loc":{
        "$geoWithin":{
            "$centerSphere":[
                [
                    0,0
                ],
                 0.025 //單位爲弧度
            ]
        }
    }
})

最後,mongodb 提供了許多更爲複雜的查詢方法,有需要的同學可以自己到官網查看。https://docs.mongodb.com/manual/reference/operator/aggregation/geoNear/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章