功能介绍

  • 拼写检查
  • 自动建议查询词(自动补全)

官网:
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html

Suggesters基本的运作原理是将输入的文本分解为token,然后在索引的字典里查找相似的term并返回。

图示:
image.png

ES查询建议API

查询建议也是使用_search端点地址,在DSL中suggest节点来定义需要的建议查询。

  1. POST twitter/_search
  2. {
  3. "query" : {
  4. "match": {
  5. "message": "tring out Elasticsearch"
  6. }
  7. },
  8. "suggest" : {
  9. "my-suggestion" : { #一个查询建议名称
  10. "text" : "tring out Elasticsearch", #查询文本
  11. "term" : {
  12. "field" : "message" #指定在哪个字段上获取建议词
  13. }
  14. }
  15. }
  16. }
  17. #多个建议查询可以使用全局的查询文本
  18. POST _search
  19. {
  20. "suggest": {
  21. "text" : "tring out Elasticsearch",
  22. "my-suggest-1" : {
  23. "term" : {
  24. "field" : "message"
  25. }
  26. },
  27. "my-suggest-2" : {
  28. "term" : {
  29. "field" : "user"
  30. }
  31. }
  32. }
  33. }

Suggester介绍

term suggester

term 词项建议器,对给入的文本进行分词,为每个词进行模糊查询提供词项建议。对于在索引中存在词默认不提供建议词,不存在的词则根据模糊查询结果进行排序后取一定数量的建议词。

image.png

phrase suggester

phrase 短语建议,在term的基础上,会考量多个term之间的关系,比如是否同时出现在索引的原文里,相邻程度,以及词频等

  1. POST /ftq/_search
  2. {
  3. "query": {
  4. "match_all": {}
  5. },
  6. "suggest" : {
  7. "myss":{
  8. "text": "java sprin boot",
  9. "phrase": {
  10. "field": "title"
  11. }
  12. }
  13. }
  14. }

completion suggester 自动补全

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html#completion-suggester
针对自动补全场景而设计的建议器。

此场景下用户每输入一个字符的时候,就需要即时发送一次查询请求到后端查找匹配项,在用户输入速度较高的情况下对后端响应速度要求比较苛刻。

因此实现上它和前面两个Suggester采用了不同的数据结构,索引并非通过倒排来完成,而是将analyze过的数据编码成FST和索引一起存放。

对于一个open状态的索引,FST会被ES整个装载到内存里的,进行前缀查找速度极快。但是FST只能用于前缀查找,这也是Completion Suggester的局限所在。

Context Suggester

完成建议者考虑索引中的所有文档,但通常希望提供经过筛选和/或由某些标准增强的建议。

实战

为了使用自动补全,索引中用来提供补全建议的字段需特殊设计,字段类型为 completion。
定义一个索引:

  1. PUT music
  2. {
  3. "mappings": {
  4. "_doc" : {
  5. "properties" : {
  6. "suggest" : {
  7. "type" : "completion" #定义该字段是自动补全的字段
  8. },
  9. "title" : {
  10. "type": "keyword"
  11. }
  12. }
  13. }
  14. }
  15. }

存入文档1和文档2,两个文档内容一样:

  1. PUT music/_doc/1?refresh
  2. {
  3. "suggest" : {
  4. "input": [ "Nevermind", "Nirvana" ], #指定输入值
  5. "weight" : 34 #指定排序值(可选)
  6. }
  7. }
  8. PUT music/_doc/2?refresh
  9. {
  10. "suggest" : {
  11. "input": [ "Nevermind", "Nirvana" ],
  12. "weight" : 20
  13. }
  14. }

查询看看:

  1. POST music/_search?pretty
  2. {
  3. "suggest": {
  4. "song-suggest" : {
  5. "prefix" : "nir",
  6. "completion" : {
  7. "field" : "suggest"
  8. }
  9. }
  10. }
  11. }
  12. POST music/_search?pretty
  13. {
  14. "suggest": {
  15. "song-suggest" : {
  16. "prefix" : "nir",
  17. "completion" : {
  18. "field" : "suggest",
  19. "skip_duplicates": true #去重
  20. }
  21. }
  22. }
  23. }

接着存入文档3和文档4,存的是短语:

  1. PUT music/_doc/3?refresh
  2. {
  3. "suggest" : {
  4. "input": [ "lucene solr", "lucene so cool","lucene elasticsearch" ],
  5. "weight" : 20
  6. }
  7. }
  8. PUT music/_doc/4?refresh
  9. {
  10. "suggest" : {
  11. "input": ["lucene solr cool","lucene elasticsearch" ],
  12. "weight" : 10
  13. }
  14. }

再查询看看:

  1. POST music/_search?pretty
  2. {
  3. "suggest": {
  4. "song-suggest" : {
  5. "prefix" : "lucene s",
  6. "completion" : {
  7. "field" : "suggest" ,
  8. "skip_duplicates": true
  9. }
  10. }
  11. }
  12. }

参考文章: https://blog.csdn.net/supermao1013/article/details/84311057