如何實現查詢附近的人
阿新 • • 發佈:2018-12-31
問題:給定一個使用者A,返回與此使用者相距小於d的所有使用者。支援GEO的後端儲存有MongoDB,Redis等。那麼如果讓我們實現,我們應該怎麼做呢?
思路:圍繞此使用者生成一個圓形,半徑是d,返回所有被此園覆蓋的使用者。
方法1: 先求方,再求園。
如果直接求園,每一個使用者都要計算距離值,無法利用到索引,可以先求方,將經度值和緯度值分別差值小於半徑的點拿出來,然後在求園,將不符合點的使用者過濾。
方法2: 位置敏感hash
MongoDB採用的就是這種方式:具體方式是先將整個地圖分為四個相等的區域,然後給每個區域賦值,比如左下方是00,左上方是01,右下方是10,右上方是11.
a. 給定一個點,算出此點在哪個區域,比如在右上方,則是11,那麼geohash的值的前兩位就是11.
b. 將右上方區域繼續切分為四個相等的區域,然後算出此點在哪個區域,如果在右下方,那麼geohash的接下來兩位就是10.
c 就這樣迭代n次,geohash的值就是2n位的。n越大,精度越高,MongoDB的預設值是26次。
然後計算相鄰的時候就比較容易了,因為hash值是位置敏感hash,所以越是相近的點那麼他們的差值就越小。
方法2的優點顯而易見,求相鄰的速度非常快,是O(1), 缺點是模擬相鄰,並不是真正的圓形等距離,不過這一缺點可以靠增加迭代次數實現,也就是精度提高。方法1的優點是嚴格的圓形等距離,但缺點是演算法複雜度根附近的使用者數相關。
作者:hongchangfirst