一 序
本文屬於極客時間Elasticsearch核心技術與實戰學習筆記系列。
二 什麼是搜索建議
- 現代的搜索引擎,一般都會提供 Suggest as you type 的功能
- 幫助用戶在輸入搜索的過程中,進行自動補全或者糾錯。通過協助用戶輸入更加精準的關鍵詞,提高後續搜索階段文檔匹配的程度
- 在 google 上搜索,一開始會自動補全。當輸入到一定長度,如因爲單詞拼寫錯誤無法補全,就會開始提示相似的詞或者句子
2.1 Elasticsearch Suggester API
- 搜索引擎中類似的功能,在 ES 中通過 Sugester API 實現的
- 原理:將輸入的文檔分解爲 Token,然後在索引的字段裏查找相似的 Term 並返回
- 根據不同的使用場景,ES 設計了 4 種類別的 Suggesters
- Term Suggester(糾錯補全,輸入錯誤的情況下補全正確的單詞)
- Phrase Suggester(自動補全短語,輸入一個單詞補全整個短語)
- Completion Suggester(完成補全單詞,輸出如前半部分,補全整個單詞)
- Context Suggester(上下文補全)
2.2Term Suggester
demo:
數據準備
DELETE articles
PUT articles
{
"mappings": {
"properties": {
"title_completion":{
"type": "completion"
}
}
}
}
POST articles/_bulk
{ "index" : { } }
{ "title_completion": "lucene is very cool"}
{ "index" : { } }
{ "title_completion": "Elasticsearch builds on top of lucene"}
{ "index" : { } }
{ "title_completion": "Elasticsearch rocks"}
{ "index" : { } }
{ "title_completion": "elastic is the company behind ELK stack"}
{ "index" : { } }
{ "title_completion": "Elk stack rocks"}
{ "index" : {} }
"suggest" : {
"term-suggestion" : [
{
"text" : "lucen",
"offset" : 0,
"length" : 5,
"options" : [
{
"text" : "lucene",
"score" : 0.8,
"freq" : 2
}
]
},
{
"text" : "rock",
"offset" : 6,
"length" : 4,
"options" : [ ]
}
]
}
搜索 “lucen rock”:看結果: "lucene",//推薦了,而rock 沒有推薦。
搜索 “lucen rock”:
- 每個建議都包含了一個算分,相似性是通過 Levenshtein Edit Distance 的算法實現的。核心思想就是一個詞改動多少字段就可以和另外一個詞一致。提供了很多可選參數來控制相似性的模糊程度。
幾種 Suggestion Mode
- Missing - 如索引中已存在,就不提供建議
- Popular - 推薦出現頻率更加高的詞
- Always - 無論是否存在,都提供建議
因爲文檔裏有兩條rocks,所以認爲popular的結果爲rocks. 換成always也是一樣的結果。
POST /articles/_search
{
"suggest": {
"term-suggestion": {
"text": "lucen rock",
"term": {
"suggest_mode": "always",
"field": "body"
}
}
}
}
如果換成hocks查詢:
返回:‘
"suggest" : {
"term-suggestion" : [
{
"text" : "lucen",
"offset" : 0,
"length" : 5,
"options" : [
{
"text" : "lucene",
"score" : 0.8,
"freq" : 2
}
]
},
{
"text" : "hocks",
"offset" : 6,
"length" : 5,
"options" : [ ]
}
]
}
}
這裏有一些相關的參數可以設置,
lowercase_terms
:表示在文本分析後,將推薦文本術語轉換成小寫;max_edits
:表示可以被選爲建議的edit distance的最大值,只能是1和2之前的數值,默認是2;prefix_length
:表示可以被選爲建議的最小前綴字符的長度,默認爲1,增加這個長度可以提高拼寫檢查的性能,通常拼寫錯誤不會發生在術語的最前面(prefix_len
參數已經丟棄);min_word_length
:表示推薦文本的最小產嘀咕,默認爲4(min_word_len
參數已被丟棄);shard_size
:表示從每個獨立碎片(分片)獲取建議的最大數量,在減少階段(reduce phase)基於size
參數的設置只返回前N個建議,默認就是size
提供的值,將shard_size
設置爲大於size
參數,可能對得到性能爲代價更準確的文檔頻率拼寫糾正更加有效,因爲術語分區中碎片,碎片級別文檔頻率的拼寫糾正可能不準確,增加這將使這些文檔頻率更精確;max_inspections
:表示一個因子,這個參數和shard_size
參數相乘以便在碎片級別檢查更多的候選者的拼寫錯誤,可以提高以性能爲代價的準確性,參數默認爲5;min_doc_freq
:表示一個建議中應包含文檔數目的最小限制,可以指定爲一個確切的數或文檔數的相對百分比,可以通過推薦高頻術語來提高質量,min_doc_freq
默認是0(即不開啓此功能),如果將這個參數指定爲一個大於1的值(不能是小數,只是大於1時不能指定爲小數),碎片級別的文檔頻率用於這個選項;max_term_freq
:表示推薦文本可以包含的文檔數目的最大限制,可以是一個代表文檔頻率的確切值,也可以是一個相對百分數(比如0.4),如果指定爲一個大於1的數(不可以指定爲小數),默認是0.01f,這個參數可以用來排除高頻術語的拼寫檢查,高頻術語通常在前幾個字符是拼寫正確的以提高拼寫檢查的性能,碎片(分片)性能文檔頻率用於這個選項;string_distance
:表示一個字符串距離用於和推薦內容相比它們之間的相似性,這個參數可能的值有5個:
internal
:表示默認的基於damerau_levenshtein算法,但在比較字符串距離內的索引已經做過高度優化;damerau_levenshtein
:是一種基於Damerau-Levenshtein算法的字符串距離算法;levenshtein
:是一種基於Levenshtein edit distance算法的字符串距離算法;jaro_winkler
:是一種基於Jaro-Winkler算法的字符串距離算法;ngram
:是一種基於字符連詞的字符串距離算法;
針對上面hocks的case:可以使用prefix_length調整最小前綴的長度
2.3 Phrase Suggester
修改下:confidence
將輸入的文本分解爲Token,然後再索引的字典裏查找相似的term 並返回 .
實際應用中應該有優化空間吧。