閱讀543 返回首頁    go 阿裏雲 go 技術社區[雲棲]


《深入理解Elasticsearch(原書第2版)》一2.4.4 後置過濾和過濾查詢

本節書摘來華章計算機《深入理解Elasticsearch(原書第2版)》一書中的第2章 ,第2.4.4節,[美]拉斐爾·酷奇(Rafal Ku) 馬雷克·羅戈任斯基(Marek Rogoziski)著 張世武 餘洪淼 商旦 譯 更多章節內容可以訪問雲棲社區“華章計算機”公眾號查看。
2.4.4 後置過濾和過濾查詢
如果某人說過濾比實現相同功能的查詢執行更快,這不一定是真的。的確,過濾器需要考慮的東西更少,並且可以在後續查詢中複用,不過Lucene早就針對查詢做了高度優化,以確保查詢能夠高速執行,甚至在考慮文檔評分的情境下。當然,如果匹配結果數量極多,過濾器會執行得更快一些。不過,還有一些事我們沒有告訴你。某些時候,在使用後置過濾(post_filter)時,Elasticsearch查詢的執行速度沒有我們期望的那麼快。假如我們執行如下查詢:
image

下圖展示了查詢的執行過程:

image


當然,針對大量數據的過濾是很有價值的。不過在本例中,我們使用現有的少量數據。從上圖可見,索引中包含4個文檔。例子中的terms查詢匹配了3個文檔:Doc1、Doc3和Doc4。每個匹配的文檔都被計算得分並根據得分做了排序。之後,post_filter開始工作。在索引的所有文檔中,它隻通過了兩個文檔:Doc1和Doc4。可以看到,一共傳遞給過濾器3個文檔,而隻有其中的兩個被作為結果輸出。既然如此,還有必要對Doc3計算得分嗎?本例我們浪費了一部分CPU時間來計算一個最終不匹配的文檔的得分。如果類似的文檔數量很多,這將是一個性能問題。
 本例中我們使用了term過濾器。該過濾器在Elasticsearch 1.5版本之前都是默認緩存的。而從1.5版本開始,默認不再緩存(參考https://github.com/Elasticsearch/Elasticsearch/pull/7583)。因此,我們在例子中使用term過濾器時特意使用了強製緩存。
讓我們修改一下這個查詢,讓文檔過濾操作發生在Scorer計算文檔得分之前。修改後的查詢如下:
image
image

在這裏我們使用了過濾查詢(filtered query)。返回的查詢結果和前一個查詢一模一樣,不過執行過程稍微有一些變化,特別是在執行過濾操作時。下圖揭示了這個查詢在理論上的執行過程:

image


現在,最初的工作是由term過濾器完成的。如果這個過濾器在之前被使用過,它將從緩存中加載,整個文檔集合將被篩成隻剩兩個文檔。最後,這兩個文檔仍然需要被計算得分,不過評分模塊需要做的工作少了一些。當然,本例中,查詢和過濾後的文檔相匹配,不過這一點並非在所有查詢場景下都滿足。
從技巧上看,我們讓過濾器被一個查詢所包裹,讓Lucene庫能夠隻收集被過濾通過的結果。當然,過濾通過的結果還需要被傳遞給主查詢做進一步處理。多虧了過濾器,打分程序需要處理的文檔數量減少了。

最後更新:2017-06-23 23:03:00

  上一篇:go  Javascript的setTimeout()使用閉包特性時需要注意的問題
  下一篇:go  ???????????????Elasticsearch????????????2????????????2.4.3???????????????-??????-????????????-?????????