文章版權由作者李曉暉和博客園共有,若轉載請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/
1.背景
地圖的基礎功能之一便為搜索,而搜索又分為正向搜索和逆向搜索。所謂正向搜索即輸入關鍵字后將匹配結果進行展示,而逆向搜索則指通過位置坐標來反向查詢附近的POI。
傳統方案中,我們將需要支持查詢數據發布成地理編碼服務,基於該服務來完成搜索。但是隨着數據的不斷豐富,點、線、面數據不斷累積,業務相關數據不斷增加,單純的興趣點搜索已不能完全滿足需求,而類似百度的全文檢索才更能滿足用戶的需求。
針對此情況,我們分別設計了正向和逆向的全文檢索方案。
2.數據存儲驗證
在最初方案中,我們考慮用ES來整合所有空間數據以支持全文的快速查詢,但是考慮ES的環境各項目需要預裝,無疑增加了項目的實施復雜度,所以我們將目光又轉移回我們各項目已普遍安裝的PG上。
由於PG的geometry字段可以同時寫入點、線、面,這樣我們可以將所有待檢索的空間數據整合至一張表中。在測試中,我們將某市的全部空間數據通過編寫工具整合,一共250萬條,全文正向搜索可以控制在1S以內,建立gist索引后,一千米內的逆向查詢也能控制在1S內,均可以滿足要求。
3.正向查詢設計
觀察百度的搜索,其搜索結果是進行了分類的。比如收索五一,其即會出現五一勞動節,也會出現五一大道,即其返回的結果並不是完全按照命中度大小來排列,而是類型+命中度等一些列加權后進行的結果排列。
這里我不討論其算法的實現,僅借鑒其分類思想,如正向搜索中,如果輸入一個關鍵字,應該在每一個分頁中對各類型數據均列出一兩個滿足的。但是,如果我們將所有類型數據整合至一張表,因為同時既要分頁,又要分類,那么對大表整體查詢其性能必然會有一定影響。我們做了如下設計:
a.按照大類將數據分別拆分至對應表中,查詢時,分別觸發對這幾張表的搜索,由於我們定義的大類目前只有四類,即四張表,雖然需要多表查詢,但是性能比之前是有提升的。
b.由於每種類型,滿足條件的結果個數並不會一致,分頁上無法保證每頁出現的各類數據一樣多。這里我們采用每頁內容數支持浮動的方案。比如,第一頁可以做到每種類型興趣點均有兩個,但是第二頁中,由於部分類型興趣點無,這第二頁中展示其他幾種興趣點數據等等,且每頁興趣點的總數無需一致(以便於后台對結果的組織)。
c.對一些類型數據優先展示,比如道路等。
d.為減少搜索時數據返回量,檢索時僅返回類型和編碼以及描述。當鼠標移入到POI上時,則觸發二次請求以獲取POI詳細信息。
以下為目前全文檢索實現結果:
4.逆向查詢設計
谷歌地圖中提供了點擊地圖時,彈出一個搜索框,可以搜索周邊數據。借用該設計邏輯,同時為了減少數據查詢次數,我們將設計規定為如下:
a.通過配置以確定是否開啟逆向搜索開關,並點擊該開關才最終開啟逆向搜索功能。
b.每一次搜索時,默認只搜索POI數據。
c.切換分類面板時,才觸發對應類型的查詢。
d.定義好前端接受的數據格式,支持第三方的查詢URL快速接入。
最終實現結果如下:
-----歡迎轉載,但保留版權,請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/
如果您覺得本文確實幫助了您,可以微信掃一掃,進行小額的打賞和鼓勵,謝謝 ^_^