基於Solr的空間搜尋 3

2021-08-27 13:33:26 字數 1581 閱讀 3188

本文將繼續介紹基於solr的地理位置搜尋的第二種實現方案

cartesiantiers+geohash

從基於solr的地理位置搜尋(2)文章中可以看到完全基於geohash的查詢過濾,將完全遍歷整個docment文件,從效率上來看並不太合適,所以結合笛卡爾層後,能有效縮減少過濾範圍,從效能上能很大程度的提高。

構建索引階段:

string geohash = geohashutils.encode(latitude, longitude);

docment.addfield(「geohash」, geohash);

//cartesian tiers

int tier = start_tier;//開始構建索引的層數

//create a bunch of tiers, each deeper level has more precision

//將一條記錄的經緯度對應全部笛卡爾層的tierboxid作為域值構建索引

for (cartesiantierplotter plotter : plotters)

看到這裡大家肯定明白了。越相近的經緯度在同層肯定會在同乙個網格中,所以他們儲存的tierboxid就會是一樣。那麼查詢的時候通過經緯度對應 層的tierboxid,也就能找到相同層域的docid,但是如果給定的的查詢範圍大,可能需要將若干層的所屬網格的docid都查到。

整個查詢過程是先通過笛卡爾層將若干個網格涉及的doclist存入bitset,如下**所示:

public docidset getdocidset(final indexreader reader) throws ioexception }

return bits; }

介紹完笛卡爾層的計算後,接下來介紹笛卡爾層過濾後返還的bitset如何和geohash結合,從實現上講其實很簡單,就是將通過笛卡爾層過濾的 資料結果集合 依次遍歷計算其與查詢給定的經緯度座標的球面距離,同時將該計算距離和查詢指定範圍距離進行比較,如果大於給定距離,則將當前記錄繼續過濾掉,那麼最終剩 下的資料結果集合,將是滿足查詢條件的地理位置結果集合。具體實現流程見如下**:

//將笛卡爾層的filter作為geohash的filter引數傳遞進去,形成乙個過濾鏈

filter = distancefilter = new geohashdistancefilter(cartesianfilter, lat, lng, miles, geohashfieldprefix);

再看geohashdistancefilter中最核心的方法getdocidset():

public docidset getdocidset(indexreader reader) throws ioexception else

//小於給定查詢距離的的docid放入快取,以供下次使用,同時返回true代表當前docid是滿足條件的記錄

if (d < distance) else }};

從上述分析中大家應該可以想到 採用笛卡爾層 filter結合gohash filter的實現方案,在計算規模上會比單獨使用geohash少了很多,而在查詢效能也會有更優異的表現。

q=*:*&fq=

查詢返回結果:

基於Solr的地理位置搜尋(3)

接上文,本文將繼續介紹基於solr的地理位置搜尋的第二種實現方案cartesian tiers geohash 從基於solr的地理位置搜尋 2 中可以看到完全基於geohash的查詢過濾,將完全遍歷整個docment文件,從效率上來看並不太合適,所以結合笛卡爾層後,能有效縮減少過濾範圍,從效能上能...

基於Solr的地理位置搜尋 1

基於solr的空間搜尋學習筆記 在solr中基於空間位址查詢主要圍繞2個概念實現 1 cartesian tiers 笛卡爾層 cartesian tiers是通過將乙個平面地圖的根據設定的層次數,將每層的分解成若干個網格,如下圖所示 每層以2的評方遞增,所以第一層為4個網格,第二層為16 個,所以...

提高solr的搜尋速度

之前是使用12台機分布式搜尋,1台為主機做索引並分發給子機,8臺做大索引搜尋服務,3 臺做小索引搜尋服務,配置基本是內存在4 8g,cpu 2 8core的伺服器,索引的大小為8g。搜尋的響應時間 是150ms左右。使用solr架構的搜尋服務 在一次技術群中,中聽到一位sina的架構師,他們是採用基...