Elasticsearch:自定义分词器实现like需求

前言

在使用ES的时候,一般常用IK分词器作为中文的分词器使用。但是有一定使用经验的小伙伴都知道。使用中文分词器的时候,经常会遇到分词不准的情况。

在一般的情况下,大家都告诉你去维护分词字典,更新索引。但是呢,又在一般的情况下,中小公司根本没有人去特地维护小项目的搜索索引。在搜索一些短语,比如公司名称的时候,需求方可能更想要类似mysql中的like实现的效果,完成模糊查询即可。

当然,在数据量不是很大的时候,直接使用ES中的wildcard完成模糊搜索即可。但是,众所周知,wildcard的搜索匹配的性能是非常低的,在有一定数据量的情况下,不建议在生产环境使用wildcard

下面介绍一种简易的代替方案:通过nGram分词器实现like需求,这种实现方案,特别适用于短句/短语搜索中。

分词器创建:
vbnet 复制代码
curl -XPUT http://127.0.0.1:9200/test_index  -H 'Content-Type: application/json' -d '{
  "settings": {
    "index": {
      "number_of_shards": 3,
      "number_of_replicas": 0
    },
    "analysis": {
      "analyzer": {
        "char_split": {
          "filter": [
            "lowercase"
          ],
          "char_filter": [
            "html_strip"
          ],
          "type": "custom",
          "tokenizer": "my_ngram_tokenizer"
        }
      },
      "tokenizer": {
        "my_ngram_tokenizer": {
          "token_chars": [
            "letter",
            "digit",
            "punctuation"
          ],
          "min_gram": "1",
          "type": "nGram",
          "max_gram": "1",
          "custom_token_chars" : ["+"]
        }
      }
    }
  }
}'

这段代码定义了一个自定义分词器,名为"char_split"。 自定义分词器的配置包含以下部分:

  1. number_of_shards:索引数据的分片数。
  2. number_of_replicas:每个分片的备份数。
  3. analyzer:定义了一个名为"char_split"的自定义分词器。
  4. filter:指定了使用的过滤器,这里只使用了一个"lowercase"过滤器,将所有字符转换为小写。
  5. char_filter:指定了使用的字符过滤器,这里只使用了一个"html_strip"字符过滤器,用于去除HTML标签。
  6. tokenizer:定义了一个自定义的分词器,名为"my_ngram_tokenizer"。
  • token_chars:指定了可以作为标记的字符类型,包括字母、数字和标点符号。
  • min_gram:指定标记的最小长度,这里设置为1。
  • type:指定使用的分词器类型,这里设置为nGram,表示按照给定长度切割文本。
  • max_gram:指定标记的最大长度,这里设置为1,表示不进行组合切割。
  • custom_token_chars:指定扩展的标记字符集合,这里包括"+"字符。

特别要注意的是对一些特殊字符的分词处理,虽然token_chars中有punctuation这个可选项,但是它不包含对 + 等常见符号的处理。如果你想要搜索 C++,那么你需要 加上"custom_token_chars" : ["+"]配置,使得分词器对+号有效。具体参数设置根据自身的需要进行调整。

elasticsearch nGram 文档

快速验证分词结果的方式:
bash 复制代码
GET /_analyze
{
  "tokenizer": {
    "type" : "ngram",
    "min_gram" : 1,
    "max_gram" : 1,
    "token_chars" : ["letter", "custom"],
    "custom_token_chars" : ["+"]
  },
  "text": ["hello-go+odwewq "]
}

创建索引时,可以根据需要合理设置多种分词结果,例如:

json 复制代码
{
  "name": {
    "type": "keyword",
    "fields": {
      "anlz_name": {
        "type": "text",
        "analyzer": "char_split",
        "search_analyzer": "char_split"
      }
    }
  }
}

最后分词器结合 match_phrase 方式使用即可实现类似like的效果

相关推荐
x***13391 小时前
【MyBatisPlus】MyBatisPlus介绍与使用
android·前端·后端
f***68603 小时前
【SpringBoot篇】详解Bean的管理(获取bean,bean的作用域,第三方bean)
java·spring boot·后端
z***75154 小时前
【Springboot3+vue3】从零到一搭建Springboot3+vue3前后端分离项目之后端环境搭建
android·前端·后端
w***95496 小时前
SQL美化器:sql-beautify安装与配置完全指南
android·前端·后端
橙子家6 小时前
Serilog 日志库简单实践(三)集中式日志与分析平台 Sinks(.net8)
后端
r***12387 小时前
Spring boot启动原理及相关组件
数据库·spring boot·后端
m***11907 小时前
【SpringBoot】Spring Boot 项目的打包配置
java·spring boot·后端
李慕婉学姐7 小时前
Springboot剪纸数字博物馆系统6wd19a3a(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
java·spring boot·后端
追逐时光者7 小时前
精选 5 款 .NET 开源、实用的商城系统(Shop),快速商城二开利器!
后端·.net