MongoDB的地理位置查詢,以及和mysql的使用對比


  MongoDB的一個特色就是具有豐富的查詢接口,比如地理位置查詢。

  在地理位置查詢上,MongoDB有着比傳統關系型數據庫的優勢,下面舉個例子。

  當前移動互聯網應用,按用戶離目標門店距離排序上的場景很多。

  比如:

  一張門店表shop_list,表結構字段包括shop_id,shop_name,lng,lat (門店id,門店名稱,以及門店的經緯度等)。

  現收集到當前用戶的所處位置的經緯度是,經度116.30759,緯度40.05748。獲取距離用戶1000m以內的100家門店,按照距離從近到遠排序。

 MySql的查詢語句如下:

SELECT shop_id,shop_name,lng,lat, ROUND(6378.138*2*ASIN(SQRT(POW(SIN((40.05748*PI()/180-lat*PI()/180)/2),2)+COS(40.05748*PI()/180)*COS(lat*PI()/180)*POW(SIN((116.30759*PI()/180-lng*PI()/180)/2),2)))*1000) AS distance
FROM shop_list
HAVING distance < 1000
ORDER BY distance LIMIT 100;

  一個這樣的計算方法,顯然mysql性能比較差。

下面的這個計算方法更快一些,效果和上面的幾乎差不多,只是距離distance並不真實。如果只想按照距離排序查出結果是沒問題的。

SELECT
    shop_id ,
    shop_name ,
    lng ,
    lat ,
    POWER(lat - 40.05748 , 2) + POWER(lng - 116.30759 , 2) * POWER(COS((lat + 40.05748) / 2) , 2) AS distance
FROM
    shop_list
HAVING
    distance < 1000
ORDER BY
    distance
LIMIT 100;

 

 

  換做MongoDB會如何呢?

  首先,要明確MongoDB在使用距離查詢時,存儲的經緯度結構要類似這樣才可以:

'point' : [
    116.299,
    40.053
]

或者: 'point' : { 'lng' : 116.299, 'lat' : 40.053 }

 

  然后給經緯度的point做一個2dSphere索引。具體參考官方文檔: 

db.shop_list.createIndex({"point":"2dsphere"})

 

第三個用法可以得出距離值:

#這個點的附近
db.shop_list.find({'point':{$nearSphere: [116.30759, 40.05748]}}) 

#這個點的附近1000米
db.shop_list.find({point: { $geoWithin: { $centerSphere: [ [ 116.30759, 40.05748 ], 1000/6378137 ] } } }) 

#這個點的附近1000米的10個門店,並且有距離計算值
db.runCommand({ geoNear : "shop_list" , near : [ 116.30759, 40.05748], num : 10 , spherical:true, distanceMultiplier: 6378137, maxDistance:1000/6378137})

 

  

  

 

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM