ElasticSearch 結構化搜索全文
1、介紹
上篇介紹了搜索結構化數據的簡單應用示例,現在來探尋 全文搜索(full-text search) :怎樣在全文字段中搜索到最相關的文檔。
全文搜索兩個最重要的方面是:
- 相關性(Relevance)
- 它是評價查詢與其結果間的相關程度,並根據這種相關程度對結果排名的一種能力,這種計算方式可以是 TF/IDF 方法(參見 相關性的介紹)、地理位置鄰近、模糊相似,或其他的某些算法。
- 分析(Analysis)
- 它是將文本塊轉換為有區別的、規範化的 token 的一個過程,(參見 分析的介紹) 目的是為了(a)創建倒排索引以及(b)查詢倒排索引。
一旦談論相關性或分析這兩個方面的問題時,我們所處的語境是關於查詢的而不是過濾。
2、基於詞項和基於全文
所有查詢會或多或少的執行相關度計算,但不是所有查詢都有分析階段。 和一些特殊的完全不會對文本進行操作的查詢(如 bool
或 function_score
)不同,文本查詢可以劃分成兩大家族:
- 基於詞項的查詢
- 如
term
或fuzzy
這樣的底層查詢不需要分析階段,它們對單個詞項進行操作。用term
查詢詞項Foo
只要在倒排索引中查找 準確詞項 ,並且用 TF/IDF 算法為每個包含該詞項的文檔計算相關度評分_score
。 -
記住
term
查詢只對倒排索引的詞項精確匹配,這點很重要,它不會對詞的多樣性進行處理(如,foo
FOO
)。這裏,無須考慮詞項是如何存入索引的。如果是將
["Foo","Bar"]
索引存入一個不分析的(not_analyzed
)包含精確值的字段,或者將Foo Bar
索引到一個帶有whitespace
空格分析器的字段,兩者的結果都會是在倒排索引中有Foo
和Bar
這兩個詞。 - 基於全文的查詢
- 像
match
或query_string
這樣的查詢是高層查詢,它們了解字段映射的信息: -
1、如果查詢
日期(date)
或整數(integer)
字段,它們會將查詢字符串分別作為日期或整數對待。2、如果查詢一個(
not_analyzed
3、但如果要查詢一個(
analyzed
)已分析的全文字段,它們會先將查詢字符串傳遞到一個合適的分析器,然後生成一個供查詢的詞項列表。一旦組成了詞項列表,這個查詢會對每個詞項逐一執行底層的查詢,再將結果合並,然後為每個文檔生成一個最終的相關度評分。
很少直接使用基於詞項的搜索,通常情況下都是對全文進行查詢,而非單個詞項,這只需要簡單的執行一個高層全文查詢(進而在高層查詢內部會以基於詞項的底層查詢完成搜索)。
當我們想要查詢一個具有精確值的 not_analyzed
未分析字段之前, 需要考慮,是否真的采用評分查詢,或者非評分查詢會更好。
單詞項查詢通常可以用是、非這種二元問題表示,所以更適合用過濾, 而且這樣做可以有效利用緩存
ElasticSearch 結構化搜索全文