ElasticSearch 搜索模板與建議

公號:碼農充電站pro
主頁:https://codeshellme.github.io

Search APIs 用於搜索聚合存儲在 ES 中的數據。

1,搜索模板 Template

Search 模板使用 mustache 語言來呈現搜索請求,使得搜索請求參數化,達到開發人員與搜索工程師解耦的效果。

示例:

# 定義一個搜索模板
POST _scripts/template_name # 模板名稱爲 template_name 
{
  "script": {           # 固定寫法
    "lang": "mustache", # 固定寫法
    "source": {         # 固定寫法
      "_source": ["title", "overview"], # 返回哪些字段
      "size": 20,
      "query": {       
        "multi_match": {
          "query": "{{q}}",     # 搜索參數,參數名爲 q
          "fields": ["title", "overview"]
        }
      }
    }
  }
}

# 使用模板
POST template_name/_search/template
{
    "id":"template_name",
    "params": {  # 填寫參數 q
        "q": "basketball with cartoon aliens"
    }
}

2,搜索建議 Suggesters

搜索建議幫助用戶在輸入搜索的過程中,進行自動補全或者糾錯,這種功能在 ES 中通過 Suggesters 來完成。

Suggesters 會將輸入的文本分解爲 token,然後在索引的字典裏查找相似的 Term 並返回。

ES 提供了 4 種類別的 Suggesters

  • Term suggester
  • Phrase Suggester
  • Completion Suggester
  • Context Suggester

Suggester Mode 用於指定在什麼情況下給出搜索建議:

  • missing:搜索不到內容時,給出搜索建議
  • popular:推薦出現頻率更高的詞
  • always:無論是否存在,都給出搜索建議

2.1,Term suggester

示例:

DELETE articles

# 插入一些文檔
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" : {} }

term-suggestion 搜索:

POST /articles/_search
{
  "size": 1,
  "query": {
    "match": {
      "body": "lucen rock"   # 查詢字符串,拼寫錯誤
    }
  },
  "suggest": {               # 搜索建議
    "term-suggestion": {     # suggester 名稱,自定義
      "text": "lucen rock",  # 這裏也是查詢字符串
      "term": {              # term-suggestion
        "suggest_mode": "missing",  # 建議模式,在沒有搜索到時,到 body 字段搜索
        "field": "body"             # 建議字段
      }
    }
  }
}

一些參數:

  • sort:排序方法,默認按照評分排序,也可以按照 frequency 排序。
  • prefix_length:默認情況下,首字母不一致就不會給出建議詞。如果將其設置爲 0,就會爲 hock 建議 rock。

示例:

POST /articles/_search
{

  "suggest": {
    "term-suggestion": {
      "text": "lucen hocks",
      "term": {
        "suggest_mode": "always",
        "field": "body",
        "prefix_length":0,
        "sort": "frequency"
      }
    }
  }
}

2.2,Phrase Suggester

Phrase SuggesterTerm Suggester 的基礎上增加了一些額外的邏輯。

一些參數:

  • max_errors:最多可以拼錯的 Terms 數
  • confidence:限制返回結果數,默認爲 1。值爲 0 的話,表示返回前 N 個結果。

示例:

POST /articles/_search
{
  "suggest": {
    "my-suggestion": {  # 一個 Suggester,自定義名稱
      "text": "lucne and elasticsear rock hello world ", # 搜索字符串
      "phrase": {           # phrase-suggestion
        "field": "body",
        "max_errors":2,
        "confidence":0,
        "direct_generator":[{
          "field":"body",
          "suggest_mode":"always"
        }],
        "highlight": {
          "pre_tag": "<em>",
          "post_tag": "</em>"
        }
      }
    }
  }
}

2.3,Completion Suggester

Completion Suggester 用於自動補全,用戶每輸入一個字符,就需要即時發送一個查詢請求到後端查找匹配項。

自動補全功能對性能要求比較高, ES 採用了不同的數據結構,而非通過倒排索引來完成。

自動補全功能將分詞數據編碼成 FST,與索引放在一起。FST 會被加載到內存中,以加快速度。FSF 的缺點是隻能用於前綴查找

示例:

首先,字段的類型必須是 completion,該數據類型用於自動補全功能。

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" : {} }

查詢數據:

POST articles/_search?pretty
{
  "size": 0,
  "suggest": {
    "article-suggester": { # 自定義名稱
      "prefix": "elk ",    # 查詢前綴,基於該前綴進行自動補全
      "completion": {      # completion 
        "field": "title_completion"  # 字段
      }
    }
  }
}

2.4,Context Suggester

Context Suggester 是對 Completion Suggester 的擴展,稱爲上下文感知推薦,可以在搜索時提供更多的上下文信息。

例如,輸入 "star":

  • 咖啡相關:建議 "starbucks"
  • 電影相關:建議 "start wars"

可以定義兩種類型的上下文:

  • Category:任意字符串
  • Geo:地理位置信息

實現 Context Suggester 的步驟:

  1. 定義一個 Mapping
  2. 索引數據,並且爲每個文檔加入 Context 信息
  3. 查詢

示例:

# 設置 Mapping
PUT comments
PUT comments/_mapping
{
  "properties": {
    "comment_autocomplete":{      # 字段名稱
      "type": "completion",       # 字段類型
      "contexts":[{               # Context Suggester,是一個數組
        "type":"category",        # 上下文類型
        "name":"comment_category" # 名稱
      }]
    }
  }
}

# 寫入數據
POST comments/_doc
{
  "comment":"I love the star war movies",
  "comment_autocomplete":{
    "input":["star wars"],        # 如果請求 movies 類型的數據,就返回 "star wars"
    "contexts":{
      "comment_category":"movies" # 自定義 movies 類型
    }
  }
}

POST comments/_doc
{
  "comment":"Where can I find a Starbucks",
  "comment_autocomplete":{
    "input":["starbucks"],        # 如果請求 coffee 類型的數據,就返回 "starbucks"
    "contexts":{
      "comment_category":"coffee" # 自定義 coffee 類型
      }
    }
  }
}

# 查詢
POST comments/_search
{
  "suggest": {
    "MY_SUGGESTION": {     # 自定義名稱
      "prefix": "sta",     # 搜索字符串前綴
      "completion":{       # 自動補全,固定寫法
        "field":"comment_autocomplete",  # 字段名稱
        "contexts":{      
          "comment_category":"coffee"    # 請求 coffee 類型的數據
        }
      }
    }
  }
}

2.5,幾種建議的指標比較

比較:

  • 精準度: Completion > Phrase > Term
  • 召回率:Term > Phrase > Completion
  • 性能:Completion > Phrase > Term

(本節完。)


推薦閱讀:

ElasticSearch 查詢

ElasticSearch URI 查詢

ElasticSearch DSL 查詢

ElasticSearch 文檔及操作

ElasticSearch 分詞器


歡迎關注作者公衆號,獲取更多技術乾貨。

碼農充電站pro

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章