Elasticsearch 查詢建議

查詢建議介紹

查詢建議是什么?

查詢建議,為用戶提供良好的使用體驗。主要包括: 拼寫檢查; 自動建議查詢詞(自動補全)

ES中查詢建議的API

查詢建議也是使用_search端點地址。在DSL中suggest節(jié)點來定義需要的建議查詢
示例1:定義單個建議查詢詞

POST twitter/_search
{
  "query" : {
    "match": {
      "message": "tring out Elasticsearch"
    }
  },
  "suggest" : { <!-- 定義建議查詢 -->
    "my-suggestion" : { <!-- 一個建議查詢名 -->
      "text" : "tring out Elasticsearch", <!-- 查詢文本 -->
      "term" : { <!-- 使用詞項建議器 -->
        "field" : "message" <!-- 指定在哪個字段上獲取建議詞 -->
      }
    }
  }
}

示例2:定義多個建議查詢詞

POST _search
{
  "suggest": {
    "my-suggest-1" : {
      "text" : "tring out Elasticsearch",
      "term" : {
        "field" : "message"
      }
    },
    "my-suggest-2" : {
      "text" : "kmichy",
      "term" : {
        "field" : "user"
      }
    }
  }
}

示例3:多個建議查詢可以使用全局的查詢文本

POST _search
{
  "suggest": {
    "text" : "tring out Elasticsearch",
    "my-suggest-1" : {
      "term" : {
        "field" : "message"
      }
    },
    "my-suggest-2" : {
       "term" : {
        "field" : "user"
       }
    }
  }
}

Suggester 介紹

Term suggester

term 詞項建議器,對給入的文本進行分詞,為每個詞進行模糊查詢提供詞項建議。對于在索引中存在詞默認不提供建議詞,不存在的詞則根據(jù)模糊查詢結(jié)果進行排序后取一定數(shù)量的建議詞。
常用的建議選項:

參數(shù) 描述
text 指定搜索文本
field 獲取建議詞的搜索字段
analyzer 指定分詞器
size 每個詞返回的最大建議詞數(shù)
sort 如何對建議詞進行排序,可用選項:
score:先按評分排序、再按照文檔頻率排、term排序
frequency:先按照文檔頻排序、再按評分、term順序排
suggest_mode 建議模式:
missing:僅在搜索的詞項在索引中不存在時才提供建議詞
popular:僅建議文檔頻率比搜索詞項高的詞
always:總是提供匹配的建議詞

示例1:

POST twitter/_search
{
  "query" : {
    "match": {
      "message": "tring out Elasticsearch"
    }
  },
  "suggest" : { <!-- 定義建議查詢 -->
    "my-suggestion" : { <!-- 一個建議查詢名 -->
      "text" : "tring out Elasticsearch", <!-- 查詢文本 -->
      "term" : { <!-- 使用詞項建議器 -->
        "field" : "message" <!-- 指定在哪個字段上獲取建議詞 -->
      }
    }
  }
}
phrase suggester

phrase 短語建議,在term的基礎(chǔ)上,會考量多個term之間的關(guān)系,比如是否同時出現(xiàn)在索引的原文里,相鄰程度,以及詞頻等
示例1:

POST /ftq/_search
{
  "query": {
    "match_all": {}
  },
  
  "suggest" : {
    "myss":{
      "text": "java sprin boot",
      "phrase": {
        "field": "title"
      }
    }
  }
}

結(jié)果1:

{
  "took": 177,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 1,
    "hits": [
      {
        "_index": "ftq",
        "_type": "_doc",
        "_id": "2",
        "_score": 1,
        "_source": {
          "title": "java spring boot",
          "content": "lucene is writerd by java"
        }
      },
      {
        "_index": "ftq",
        "_type": "_doc",
        "_id": "1",
        "_score": 1,
        "_source": {
          "title": "lucene solr and elasticsearch",
          "content": "lucene solr and elasticsearch for search"
        }
      }
    ]
  },
  "suggest": {
    "myss": [
      {
        "text": "java sprin boot",
        "offset": 0,
        "length": 15,
        "options": [
          {
            "text": "java spring boot",
            "score": 0.20745796
          }
        ]
      }
    ]
  }
}
Completion suggester 自動補全

針對自動補全場景而設(shè)計的建議器。此場景下用戶每輸入一個字符的時候,就需要即時發(fā)送一次查詢請求到后端查找匹配項,在用戶輸入速度較高的情況下對后端響應(yīng)速度要求比較苛刻。因此實現(xiàn)上它和前面兩個Suggester采用了不同的數(shù)據(jù)結(jié)構(gòu),索引并非通過倒排來完成,而是將analyze過的數(shù)據(jù)編碼成FST和索引一起存放。對于一個open狀態(tài)的索引,F(xiàn)ST會被ES整個裝載到內(nèi)存里的,進行前綴查找速度極快。但是FST只能用于前綴查找,這也是Completion Suggester的局限所在。
為了使用自動補全,索引中用來提供補全建議的字段需特殊設(shè)計,字段類型為 completion。

PUT music
{
    "mappings": {
        "_doc" : {
            "properties" : {
                "suggest" : {  <!-- 用于自動補全的字段 -->
                    "type" : "completion"
                },
                "title" : {
                    "type": "keyword"
                }
            }
        }
    }
}

Input 指定輸入詞 Weight 指定排序值(可選)

PUT music/_doc/1?refresh
{
    "suggest" : {
        "input": [ "Nevermind", "Nirvana" ],
        "weight" : 34
    }
}

指定不同的排序值:

PUT music/_doc/1?refresh
{
    "suggest" : [
        {
            "input": "Nevermind",
            "weight" : 10
        },
        {
            "input": "Nirvana",
            "weight" : 3
        }
    ]}

放入一條重復(fù)數(shù)據(jù)

PUT music/_doc/2?refresh
{
    "suggest" : {
        "input": [ "Nevermind", "Nirvana" ],
        "weight" : 20
    }
}

示例1:查詢建議根據(jù)前綴查詢:

POST music/_search?pretty
{
    "suggest": {
        "song-suggest" : {
            "prefix" : "nir", 
            "completion" : { 
                "field" : "suggest" 
            }
        }
    }
}

結(jié)果1:

{
  "took": 25,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 0,
    "max_score": 0,
    "hits": []
  },
  "suggest": {
    "song-suggest": [
      {
        "text": "nir",
        "offset": 0,
        "length": 3,
        "options": [
          {
            "text": "Nirvana",
            "_index": "music",
            "_type": "_doc",
            "_id": "2",
            "_score": 20,
            "_source": {
              "suggest": {
                "input": [
                  "Nevermind",
                  "Nirvana"
                ],
                "weight": 20
              }
            }
          },
          {
            "text": "Nirvana",
            "_index": "music",
            "_type": "_doc",
            "_id": "1",
            "_score": 1,
            "_source": {
              "suggest": [
                "Nevermind",
                "Nirvana"
              ]
            }
          }
        ]
      }
    ]
  }
}

示例2:對建議查詢結(jié)果去重

POST music/_search?pretty
{
    "suggest": {
        "song-suggest" : {
            "prefix" : "nir", 
            "completion" : { 
                "field" : "suggest",
                "skip_duplicates": true 
            }
        }    }}

結(jié)果2:

{
  "took": 4,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 0,
    "max_score": 0,
    "hits": []
  },
  "suggest": {
    "song-suggest": [
      {
        "text": "nir",
        "offset": 0,
        "length": 3,
        "options": [
          {
            "text": "Nirvana",
            "_index": "music",
            "_type": "_doc",
            "_id": "2",
            "_score": 20,
            "_source": {
              "suggest": {
                "input": [
                  "Nevermind",
                  "Nirvana"
                ],
                "weight": 20
              }
            }
          }
        ]
      }
    ]
  }
}

示例3:查詢建議文檔存儲短語

PUT music/_doc/3?refresh
{
    "suggest" : {
        "input": [ "lucene solr", "lucene so cool","lucene elasticsearch" ],
        "weight" : 20
    }
}

PUT music/_doc/4?refresh
{
    "suggest" : {
        "input": ["lucene solr cool","lucene elasticsearch" ],
        "weight" : 10
    }
}

查詢3:

POST music/_search?pretty
{
    "suggest": {
        "song-suggest" : {
            "prefix" : "lucene s", 
            "completion" : { 
                "field" : "suggest" ,
                "skip_duplicates": true
            }
        }
    }
}

結(jié)果3:

{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 0,
    "max_score": 0,
    "hits": []
  },
  "suggest": {
    "song-suggest": [
      {
        "text": "lucene s",
        "offset": 0,
        "length": 8,
        "options": [
          {
            "text": "lucene so cool",
            "_index": "music",
            "_type": "_doc",
            "_id": "3",
            "_score": 20,
            "_source": {
              "suggest": {
                "input": [
                  "lucene solr",
                  "lucene so cool",
                  "lucene elasticsearch"
                ],
                "weight": 20
              }
            }
          },
          {
            "text": "lucene solr cool",
            "_index": "music",
            "_type": "_doc",
            "_id": "4",
            "_score": 10,
            "_source": {
              "suggest": {
                "input": [
                  "lucene solr cool",
                  "lucene elasticsearch"
                ],
                "weight": 10
              }
            }
          }
        ]
      }
    ]
  }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容