如何实现网页搜索自动补全功能,Elasticsearch请求“出战”

745 阅读3分钟

本篇文章主要介绍Elasticsearch搜索引擎之自动补全功能的介绍与使用。

以下正文开始

拼音分词器

当我们再很多网站输入拼音,关键字时,会出现商品,词语,与之有关联的的自动补全功能,可以帮助用户搜索到自己想要的结果。

Elasticsearch恰好能帮助我们完成这一业务。想要使用拼音来搜索商品,就需要使用拼音分词,根据字母做补全功能,就需要对文档按照拼音来分词。

首先我们需要安装拼音分词插件,将拼音分词插件下载到挂载的es-plugins目录下。下载完成后,我们可以测试一下是否可以,DSL代码如下:

POST /_analyze
{
  "text": ["小威要向诸佬学习呀"],
  "analyzer": "pinyin"
}

发送请求可以看到确实是按照拼音分词得到的结果,在创建索引库的时候可以以拼音分词的形式来创建: 在这里插入图片描述

自定义分词器

上面我们演示了使用拼音来做分词,但是上面是根据单个和组合的拼音来做分词的。在生产环境中,我们往往需要以拼音和汉字词语一起作为分词,这就需要我们来自定义分词器了。

elasticsearch中分词器(analyzer)的组成包含三部分:

  • character filters:在tokenizer之前对文本进行处理。例如删除字符、替换字符
  • tokenizer:将文本按照一定的规则切割成词条(term)。例如keyword,就是不分词;还有ik_smart
  • tokenizer filter:将tokenizer输出的词条做进一步处理。例如大小写转换、同义词处理、拼音处理等

在这里插入图片描述我们可以在创建索引库时,通过settings来配置自定义的分词器(analyzer):

// 自定义拼音分词器
PUT /test
{
  "settings": {
    "analysis": {
      "analyzer": { 
        "my_analyzer": { 
          "tokenizer": "ik_max_word",
          "filter": "py"
        }
      },
      "filter": { //自定义tokenizer filter
        "py": { //过滤器名称
          "type": "pinyin", //过滤器类型为pinyin
          "keep_full_pinyin": false,
          "keep_joined_full_pinyin": true,
          "keep_original": true,
          "limit_first_letter_length": 16,
          "remove_duplicated_term": true,
          "none_chinese_pinyin_tokenize": false
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
        "analyzer": "my_analyzer"//分词使用自定义分词器
        , "search_analyzer": "ik_smart"//搜索使用ik分词器
      }
    }
  }
}

在上面创建的索引库中放入两条文档:

{
  "id": 1,
  "name": "狮子"
}
POST /test/_doc/2
{
  "id": 2,
  "name": "虱子"
}

在这里插入图片描述 由于搜索时设置的根据ik_smart分词器进行分词,所以搜索结果只有狮子一条: 在这里插入图片描述

为了避免搜索到同音字,在创建索引库是时使用拼音分词器,在搜索时尽量不用。

completion suggester

es提供了completion suggester查询来实现自动补全功能,这个查询的概念就是匹配用户输入内容开头的词条并返回,对于文档中字段的类型,要遵循:参与补全查询的字段必须是completion类型;并且字段值是多个词条形成的数组。 举个栗子: 第一步,创建自动补全的索引库

# 创建自动补全的索引库
PUT test2
{
  "mappings": {
    "properties": {
      "title":{
        "type": "completion"
      }
    }
  }
}

第二步,在创建的索引库中插入几条补全数据:

# 示例数据
POST test2/_doc
{
  "title": ["Sony", "WH-1000XM3"]
}
POST test2/_doc
{
  "title": ["SK-II", "PITERA"]
}
POST test2/_doc
{
  "title": ["Nintendo", "switch"]
}

第三步,编写DSL语句,实现自动补全功能:

# 自动补全查询
POST /test/_search
{
  "suggest": {
    "title_suggest": {
      "text": "s", // 搜索关键字s开头的数据
      "completion": {
        "field": "title", // 补全字段
        "skip_duplicates": true, // 跳过重复的
        "size": 10 // 获取前10条结果
      }
    }
  }
}

执行上述的DSL语句,得到如下查询结果: 在这里插入图片描述

好了,本篇文章就先分享到这里了,后续会继续分享其他方面的知识,感谢大佬认真读完支持咯~