目錄
在建議器簡介部分,我們已經對term suggest
建議器有所了解。
詞條建議器接收輸入的文本,對其進行分析並且分為詞條,然后為每個詞條提供一系列的建議。
准備數據:
PUT s2
{
"mappings": {
"doc": {
"properties": {
"title": {
"type": "text",
"analyzer": "standard"
}
}
}
}
}
PUT s2/doc/1
{
"title": "Lucene is cool"
}
PUT s2/doc/2
{
"title": "Elasticsearch builds on top of lucene"
}
PUT s2/doc/3
{
"title": "Elasticsearch rocks"
}
PUT s2/doc/4
{
"title": "Elastic is the company behind ELK stack"
}
PUT s2/doc/5
{
"title": "elk rocks"
}
PUT s2/doc/6
{
"title": "elasticsearch is rock solid"
}
我們創建一個新的索引並且添加了幾條文檔。現在,我們來查詢一下吧。
GET s2/doc/_search
{
"suggest": {
"my_suggest": {
"text": "luenc",
"term": {
"field": "title"
}
}
}
}
返回的了建議結果:
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 0,
"max_score" : 0.0,
"hits" : [ ]
},
"suggest" : {
"my_suggest" : [
{
"text" : "luenc",
"offset" : 0,
"length" : 5,
"options" : [
{
"text" : "lucene",
"score" : 0.6,
"freq" : 2
}
]
}
]
}
}
上例中,在options
字段中,建議結果是lucene
。我們來看看,在建議器中,都有哪些字段。
- text:建議文本,建議文本是必需的選項,可以通過全局(多個建議器中查詢相同的內容)或者按照單個建議器的格式來。
- field:從field字段中獲取候選建議的字段。這是一個必需的選項,需要全局設置或根據建議設置。
- analyzer:用於分析建議文本的分析器。默認為建議字段的搜索分析器。
- size:個建議文本標記返回的最大條目。
- sort:定義如何根據建議文本術語對建議進行排序。它有兩個可能的值。
- score,先按分數排序,然后按文檔頻率排序,再按術語本身排序。
- frequency,首先按文檔頻率排序,然后按相似性分數排序,然后按術語本身排序。也可以理解為按照流行度排序。
- suggest_mode:控制建議的模式,有3個模式可選擇。
- missing,僅為不在索引中的建議文本術語提供建議。這是默認值。
- popular,僅建議在比原始建議文本術語更多的文檔中出現的建議。也就是說提供比原有輸入詞頻更高的詞條
- always,根據建議文本中的條款建議任何匹配的建議。說白了就是無論如何都會提供建議。
- lowercase_terms:在文本分析之后降低建議文本術語的大小寫。
- min_word_length:建議文本術語必須具有的最小長度才能包含在內。默認為4.(舊名稱
min_word_len
已棄用)。 - shard_size:設置從每個單獨分片中檢索的最大建議數。在減少階段,僅根據size選項返回前N個建議。默認為該 size選項。將此值設置為高於該值的值size可能非常有用,以便以性能為代價獲得更准確的拼寫更正文檔頻率。由於術語在分片之間被划分,因此拼寫校正頻率的分片級文檔可能不准確。增加這些將使這些文檔頻率更精確。
- max_inspections:用於乘以的因子, shards_size以便在碎片級別上檢查更多候選拼寫更正。可以以性能為代價提高准確性。默認為5。
- string_distance:用於比較類似建議術語的字符串距離實現。
- internal,默認值基於damerau_levenshtein,但高度優化用於比較索引中術語的字符串距離。
- damerau_levenshtein,基於Damerau-Levenshtein算法的字符串距離算法。
- levenshtein,基於Levenshtein編輯距離算法的字符串距離算法。
- jaro_winkler,基於Jaro-Winkler算法的字符串距離算法。
- ngram,基於字符n-gram的字符串距離算法。
選擇哪些詞條被建議
了解了各字段的大致含義,我們來探討一下,詞條建議器是如何運作的。以便理解如何確定哪些建議將成為第一名。
詞條建議器使用了Lucene的錯拼檢查器模塊,該模塊會根據給定詞條的編輯距離(es使用了叫做Levenstein edit distance的算法,其核心思想就是一個詞改動多少字符就可以和另外一個詞一致),從索引中返回最大編輯距離不超過某個值的那些詞條。比如說為了從mik
得到mick
,需要加入一個字母(也就是說需要至少要改動一次),所以這兩個詞的編輯距離就是1。我們可以通過配置一系列的選項,來均衡靈活和性能:
- max_edits:最大編輯距離候選建議可以具有以便被視為建議。只能是介於1和2之間的值。任何其他值都會導致拋出錯誤的請求錯誤。默認為2。
- prefix_length:必須匹配的最小前綴字符的數量才是候選建議。默認為1.增加此數字可提高拼寫檢查性能。通常拼寫錯誤不會出現在術語的開頭。(舊名
prefix_len
已棄用)。 - min_doc_freq:建議應出現的文檔數量的最小閾值。可以指定為絕對數字或文檔數量的相對百分比。這可以僅通過建議高頻項來提高質量。默認為0f且未啟用。如果指定的值大於1,則該數字不能是小數。分片級文檔頻率用於此選項。
- max_term_freq:建議文本令牌可以存在的文檔數量的最大閾值,以便包括在內。可以是表示文檔頻率的相對百分比數(例如0.4)或絕對數。如果指定的值大於1,則不能指定小數。默認為0.01f。這可用於排除高頻術語的拼寫檢查。高頻術語通常拼寫正確,這也提高了拼寫檢查的性能。分片級文檔頻率用於此選項。
小結,term suggester
首先將輸入文本經過分析器(所以,分析結果由於采用的分析器不同而有所不同)分析,處理為單個詞條,然后根據單個詞條去提供建議,並不會考慮多個詞條之間的關系。然后將每個詞條的建議結果(有或沒有)封裝到options
列表中。最后由建議器統一返回。
see also: [Elasticsearch Suggester詳解](https://elasticsearch.cn/article/142) | [Elasticsearch官網:Suggesters](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html) | [ElasticSearch suggester](https://blog.csdn.net/zhanglh046/article/details/78536021) | [Elasticsearch官網:suggesters-term](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-term.html)
歡迎斧正,that's all