查詢建議介紹
查詢建議是什么?
查詢建議,為用戶提供良好的使用體驗。主要包括: 拼寫檢查; 自動建議查詢詞(自動補全)
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
}
}
}
]
}
]
}
}