首先,環境是elasticsearch版本是5.x以上。低版本的沒有測試!
目前為止,瀏覽器都已經具備Suggest as you type
功能,即在我們輸入搜索的過程中,進行自動的補全或者糾錯功能,協助用戶輸入更精確的關鍵詞,提高搜索階段的文檔匹配程度。例如我們在百度或谷歌瀏覽器輸入搜索關鍵詞時,雖然我們輸入的有誤,但是瀏覽器依然能夠提示出我們想要的正確結果。
在谷歌瀏覽器中,再輸入剛開始時,會自動補全,而當輸入內容達到一定長度時,如果因為單詞拼寫錯誤而無法補全時,就開始嘗試提示相似的詞。
這些功能,我們能通過elasticsearch實現嗎?答案就在Suggesters API中。
在elasticsearch中,建議功能通過使用建議器基於提供的文本建議類似的詞(官網說部分功能仍在開發中.........)。
注意,目前_suggest
已經棄用,我們可以通過_search
來做建議器的查詢。在5.0版本中,_search
經過優化,變得非常的方便。
PUT s1
{
"mappings": {
"doc": {
"properties": {
"title": {
"type": "text",
"analyzer": "standard"
}
}
}
}
}
PUT s1/doc/1
{
"title": "Lucene is cool"
}
PUT s1/doc/2
{
"title":"Elasticsearch builds on top of lucene"
}
GET s1/doc/_search
{
"query": {
"match": {
"title": "Lucene"
}
},
"suggest": {
"my_suggest": {
"text": "Elasticsear lucen",
"term": {
"field": "title"
}
}
}
}
上例是一個包含建議的查詢請求,查詢query
我們已經了然。
讓我們注意suggest
,每個建議器都有自己名稱my-suggestion
,es根據text
字段返回建議結果。建議類型是term
。從field
字段生成建議。
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "s1",
"_type" : "doc",
"_id" : "2",
"_score" : 0.2876821,
"_source" : {
"title" : "Elasticsearch builds on top of lucene"
}
},
{
"_index" : "s1",
"_type" : "doc",
"_id" : "1",
"_score" : 0.2876821,
"_source" : {
"title" : "Lucene is cool"
}
}
]
},
"suggest" : {
"my_suggest" : [
{
"text" : "elasticsear",
"offset" : 0,
"length" : 11,
"options" : [
{
"text" : "elasticsearch",
"score" : 0.8181818,
"freq" : 1
}
]
},
{
"text" : "lucen",
"offset" : 12,
"length" : 5,
"options" : [
{
"text" : "lucene",
"score" : 0.8,
"freq" : 2
}
]
}
]
}
}
正如結果所示。對於輸入的每個詞條的建議結果,es都會放在options
中,如果沒有建議結果,options
將會為空。
如果我們僅需要建議而不需要查詢功能,我們可以忽略query
而直接使用suggest
對象返回建議:
GET s1/doc/_search
{
"suggest": {
"my_sugget": {
"text": "Elasticsear lucen",
"term": {
"field": "title"
}
}
}
}
可以根據需要指定幾組建議器,每組建議器都有自己的名稱。如下例的my_suggest1
和my_suggest2
。
GET s1/doc/_search
{
"suggest": {
"my_sugget1": {
"text": "Elasticsear",
"term": {
"field": "title"
}
},
"my_suggest2": {
"text": "lucen",
"term": {
"field": "title"
}
}
}
}
在多個建議器中,如果輸入的text
字段值一致,可以單獨寫出來,以適用於my_suggest1
和my_suggest2
兩個建議器:
GET s1/doc/_search
{
"suggest": {
"text": "Elasticsear lucen",
"my_sugget1": {
"term": {
"field": "title"
}
},
"my_suggest2": {
"term": {
"field": "title"
}
}
}
}
根據需求不同elasticsearch設計了4種suggester,分別是:
- 詞條建議器(term suggester):對於給定文本的每個詞條,該鍵議器從索引中抽取要建議的關鍵詞,這對於短字段(如分類標簽)很有效。
- 詞組建議器(phrase suggester):我們可以認為它是詞條建議器的擴展,為整個文本(而不是單個詞條)提供了替代方案,它考慮了各詞條彼此臨近出現的頻率,使得該建議器更適合較長的字段,比如商品的描述。
- 完成建議器(completion suggester):該建議器根據詞條的前綴,提供自動完成的功能(智能提示,有點最左前綴查詢的意思),為了實現這種實時的建議功能,它得到了優化,工作在內存中。所以,速度要比之前說的
match_phrase_prefix
快的多! - 上下文建議器(context suggester):它是完成建議器的擴展,允許我們根據詞條或分類亦或是地理位置對結果進行過濾。
see also: [elasticsearch官網:Suggesters](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html) 歡迎斧正,that's all