LBS 應用中「附近的人」索引是走隊列、用 solr 抑或其它技術?

主要是想了解下高並發情況下的性能問題解決,Redis+geohash並不符合我們的需求


  1. 資料庫空間索引(Spatial Indexing)

    主流資料庫(MySQL 5.0+、Oracle、PostgreSQL、SQL Server) 都在不同程度上支持歐空間索引,其中有一個類型就是 Point,可以用於存儲每個用戶所處位置的經緯度。

    有的資料庫廠家直接提供了 OpenGIS 標準函數,最方便的就是 DISTANCE,直接按照 DISTANCE 排序。

  2. 傳統資料庫索引

    存儲用戶登入欄位主要包括 userId,lat,lng。分別代表用戶 ID、最近一次 check-in 的經度、緯度。

    lat/lng 建立複合索引。

    然後通過手機的定位,得到自己的位置,比如記為 myLat,myLng。

    代碼如下,先做一個計算,算出 1km 所對應的經緯度範圍:

    double range = 180 / Math.PI * 1 / 6372.797; //裡面的 1 就代表搜索 1km 之內,單位km

    double lngR = range / Math.cos(myLat * Math.PI / 180.0);

    double maxLat = myLat + range;

    double minLat = myLat - range;

    double maxLng = myLng + lngR;

    double minLng = myLng - lngR;

    然後執行 SQL :

    SELECT xxxx FROM checkinTable WHERE ((lat BETWEEN ? AND ?) AND (lng BETWEEN ? AND ?)) LIMIT 100

    這四個問號,分別代入變數

    minLat、maxLat、minLng、maxLng

    然後就可以查詢得到結果

    但是,這樣得到的結果不是有序的。

    如果要排序,在程序代碼(比如 app 客戶端)執行。

    不建議在 SQL 層上執行,因為上述的那個 SQL 是可以用到索引進行查詢的,一旦引入排序後,索引就無法發揮作用,從而會影響效率。


Lucene有類似的包,搜索Lucene Spatial會有結果的。我們的app空間搜索是基於lucene做的。lucene端做好了。速度還行,容忍性低的話可以去該spatial包代碼


如何分頁啊?


上們服務多少錢


這個在KVDB如何實現呢,求妙解


隊列?queue?你說的是FIFO的queue嗎還是我理解錯了,這和空間位置計算有什麼關係呢?


mongodb pgsql 是首選 其次就是lucene es搜索 再就是redis geo索引


將地球推開成一個平面,變成一個大表格,這樣附近搜索其實就變成一個九宮格搜索。樓主可以朝這樣的思路去試下。


解決這個問題比較討巧的方式是與其費力氣去算一個圓周內的用戶,不如直接計算一個矩形內的用戶,這樣只要比較lat和lon即可(select * from users where lat+1 &> $current_lat &> lat-1 and lon+1 &> $current_lon &> $lon-1),雖然精度不準,但大多數情況下已經夠用,但貴在速度飛快,實時性也有保障。


mongodn自帶算距離功能是怎麼解決的?


推薦閱讀:

TAG:陌陌 | 查找附近的人 | 附近的人 | 遇見 |