ElasticSearch搜索建议与上下文提示

无所事事1年前日常记录458

搜索建议

通过Suggester Api实现

原理是将输入的文本分解为Token,然后在词典中查找类似的Term返回

根据不同场景,ElasticSearch设计了4中类别的Suggesters。

  • Term Suggester

  • Phrase Suggester

  • Complete Suggester

  • Context Suggester

Term Suggester

类似Google搜索引擎,我给的是一个错误的单词elasticserch,但引擎友好地给出了搜索建议。

1.png

要实现这个功能,在ElasticSearch中很简单。

  1. 创建索引,并写入一些文档

    POST articles/_bulk
    { "index" : { } }
    { "body": "lucene is very cool"}
    { "index" : { } }
    { "body": "Elasticsearch builds on top of lucene"}
    { "index" : { } }
    { "body": "Elasticsearch rocks"}
    { "index" : { } }
    { "body": "elastic is the company behind ELK stack"}
    { "index" : { } }
    { "body": "Elk stack rocks"}
    { "index" : {} }
    {  "body": "elasticsearch is rock solid"}
  2. 搜索文档,调用suggest api。

    当中有3种Suggestion Mode

    • missing 索引中已经存在,就不提供建议

    • popular 推荐出现频率更加高的词

    • always 无论是否存在,都提供建议

      POST /articles/_search
      {
        "size": 1,
        "query": {
          "match": {
            "body": "elasticserch"
          }
        },
        "suggest": {
          "term-suggestion": {
            "text": "elasticserch",
            "term": {
              "suggest_mode": "missing",
              "field": "body"
            }
          }
        }
      }
  3. 返回结果

    {
      "took" : 6,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 0,
          "relation" : "eq"
        },
        "max_score" : null,
        "hits" : [ ]
      },
      "suggest" : {
        "term-suggestion" : [
          {
            "text" : "elasticserch",
            "offset" : 0,
            "length" : 12,
            "options" : [
              {
                "text" : "elasticsearch",
                "score" : 0.9166667,
                "freq" : 3
              }
            ]
          }
        ]
      }
    }

Phrase Suggester

Phrase Suggester可以在Term Suggester上增加一些额外的逻辑

其中一些参数

  • max_errors 最多可以拼错的terms

  • confidence 限制返回结果数,默认1

    POST /articles/_search
    {
      "suggest": {
        "my-suggestion": {
          "text": "lucne and elasticsear rock hello world ",
          "phrase": {
            "field": "body",
            "max_errors":2,
            "confidence":2,
            "direct_generator":[{
              "field":"body",
              "suggest_mode":"missing"
            }],
            "highlight": {
              "pre_tag": "<em>",
              "post_tag": "</em>"
            }
          }
        }
      }
    }

Completion Suggester

自动完成功能,用户每输入一个字符。就需要即时发送一个查询请求到后端查找匹配项。

它对性能要求比较苛刻。

elastic将Analyse的数据编码成FST与索引放在一起,它会被整个加载进内存里面,速度非常快

FST只能支持前缀查找。

类似百度这样的提示功能

2.png

在ElasticSearch要实现这样的功能也很简单。

  1. 建立索引

    PUT titles
    {
      "mappings": {
        "properties": {
          "title_completion":{
            "type": "completion"
          }
        }
      }
    }
  2. 写入文档

    POST titles/_bulk
    { "index" : { } }
    { "title_completion": "php是什么"}
    { "index" : { } }
    { "title_completion": "php是世界上最好的语言"}
    { "index" : { } }
    { "title_completion": "php货币"}
    { "index" : { } }
    { "title_completion": "php面试题2019"}
  3. 搜索数据

    POST titles/_search?pretty
    {
      "size": 0,
      "suggest": {
        "article-suggester": {
          "prefix": "php",
          "completion": {
            "field": "title_completion"
          }
        }
      }
    }
  4. 返回结果

    {
      "took" : 173,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 0,
          "relation" : "eq"
        },
        "max_score" : null,
        "hits" : [ ]
      },
      "suggest" : {
        "article-suggester" : [
          {
            "text" : "php",
            "offset" : 0,
            "length" : 3,
            "options" : [
              {
                "text" : "php是世界上最好的语言",
                "_index" : "titles",
                "_type" : "_doc",
                "_id" : "pv8V8WwBISxFcLcZfDXl",
                "_score" : 1.0,
                "_source" : {
                  "title_completion" : "php是世界上最好的语言"
                }
              },
              {
                "text" : "php是什么",
                "_index" : "titles",
                "_type" : "_doc",
                "_id" : "pf8V8WwBISxFcLcZfDXl",
                "_score" : 1.0,
                "_source" : {
                  "title_completion" : "php是什么"
                }
              },
              {
                "text" : "php货币",
                "_index" : "titles",
                "_type" : "_doc",
                "_id" : "p_8V8WwBISxFcLcZfDXl",
                "_score" : 1.0,
                "_source" : {
                  "title_completion" : "php货币"
                }
              },
              {
                "text" : "php面试题2019",
                "_index" : "titles",
                "_type" : "_doc",
                "_id" : "qP8V8WwBISxFcLcZfDXl",
                "_score" : 1.0,
                "_source" : {
                  "title_completion" : "php面试题2019"
                }
              }
            ]
          }
        ]
      }
    }

Context Suggester

是Completion Suggester的扩展,加入了上下文信息场景。

例如:

你在电器商城,输入苹果,想要找到的苹果笔记本...
你在水果商城,输入苹果,想要找的是红苹果、绿苹果...

  1. 建立索引,定制mapping

    PUT comments
    {
      "mappings": {
        "properties": {
          "comment_autocomplete": {
            "type": "completion",
            "contexts": [
              {
                "type": "category",
                "name": "comment_category"
              }
            ]
          }
        }
      }
    }
  2. 并为每个文档加入Context信息

    POST comments/_doc
    {
      "comment":"苹果电脑",
      "comment_autocomplete":{
        "input":["苹果电脑"],
        "contexts":{
          "comment_category":"电器商城"
        }
      }
    }
    
    POST comments/_doc
    {
      "comment":"红红的冰糖心苹果",
      "comment_autocomplete":{
        "input":["苹果"],
        "contexts":{
          "comment_category":"水果商城"
        }
      }
    }
  3. 结合Context进行Suggestion查询

    POST comments/_search
    {
      "suggest": {
        "MY_SUGGESTION": {
          "prefix": "苹",
          "completion":{
            "field":"comment_autocomplete",
            "contexts":{
              "comment_category":"电器商城"
            }
          }
        }
      }
    }
  4. 返回结果

    {
      "took" : 1,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 0,
          "relation" : "eq"
        },
        "max_score" : null,
        "hits" : [ ]
      },
      "suggest" : {
        "MY_SUGGESTION" : [
          {
            "text" : "苹",
            "offset" : 0,
            "length" : 1,
            "options" : [
              {
                "text" : "苹果",
                "_index" : "comments",
                "_type" : "_doc",
                "_id" : "qf_s9WwBISxFcLcZszWh",
                "_score" : 1.0,
                "_source" : {
                  "comment" : "苹果电脑",
                  "comment_autocomplete" : {
                    "input" : [
                      "苹果电脑"
                    ],
                    "contexts" : {
                      "comment_category" : "电器商城"
                    }
                  }
                },
                "contexts" : {
                  "comment_category" : [
                    "电器商城"
                  ]
                }
              }
            ]
          }
        ]
      }
    }

附录

本文来源:ElasticSearch搜索建议与上下文提示 - 大数据学习笔记 - SegmentFault 思否

相关文章

XunSearch设置为服务 开机自动启动

开机自动启动[Uint] Description=xunsearch   [Service] Type=forking ExecStart=/bin/sh /usr/lo...

elasticsearch 开机自启动——/etc/init.d

开机自启动,就是在系统启动后,自行启动elasticsearch,无需手动启动。一、查看已存在的开机启动项[root@qf01 ~]# chkconfig --list显...

CentOS8.0安装迅搜(XunSearch)引擎报错的解决办法

在一些小型项目上需要应用全文搜索引擎时,我比较喜欢使用迅搜,因为部署方便,调用简单,今天给客户部署系统安装迅搜时,竟然有报错(极少遇到报错的情况),花了一些时间查资料,终于解决了,分享一下经验首先是定...

xunsearch实战经验总结

一、定义好配置文件(非常关键)  a):如果需要做精确搜索建议对字段设定index=self,tokenizer = full,不然xunsearch会对字段做分词处理;  b):数字区间搜索需设定&...

关于使用讯搜(xunsearch)过程中遇到的坑

1. 在xunsearch中按区间搜索的方法`$search->addRange('字段名','from','to')`- 第一个参数为字段名-...

Elasticsearch之中文分词器插件es-ik的自定义词库

【 ik 自定义词库步骤】1:创建词典首先在 ik 插件的 config/custom 目录下创建一个文件 zhouls.dic (当然这个你可以自己命名,如my.dic都行)在文件中添加词语即可,...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。