Elasticsearch自定义分词,从一个问题说开去

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 来自星友的一个真实业务场景问题:我现在的业务需求是这样的。有一个作者字段,比如是这样的Li,LeiLei;Han,MeiMei;还有一些是LeiLei Li...。现在要精确匹配。 我的想法是:用自定义分词通过分号分词。但是这样我检索Li,LeiLei那么LeiLei Li就不能搜索到,我希望的结果是LeiLei Li也被搜索到而且这种分词,Li,LeiLei不加逗号,也不能匹配到。但是不知道为什么我在mapping里面添加停用词也不管用?

image.png

链接

2、本文思路

从问题出发,由浅入深逐步探讨


为什么需要分词?

文档转换为倒排索引,发生了什么?

Elasticsearch自带的分词器

自定义分词器的模板

针对问题,实践一把

3、为什么需要分词?

中文分词是自然语言处理的基础。


语义维度:单字很多时候表达不了语义,词往往能表达。分词相当于预处理,能使后面和语义有关的分析更准确。

存储维度:如果所有文章按照单字来索引,需要的存储空间和搜索计算时间就要多的多。

时间维度:通过倒排索引,我们能以o(1) 的时间复杂度,通过词组找到对应的文章。

同理的,英文或者其他语种也需要分词。


设计索引的Mapping阶段,要根据业务用途确定是否需要分词,如果不需要分词,建议设置keyword类型;需要分词,设置为text类型并指定分词器。


推荐阅读:干货 | 论Elasticsearch数据建模的重要性


分词使用的时机:

1)创建或更新文档时,会对文档做分词处理。

2)查询时,会对查询语句进行分词处理。


4、文档转换为倒排索引,发生了什么?

**注意:**如下文档中部分关键词的翻译后反而不好理解,部分关键词我会使用和官方一致的英文关键词。

文档被发送并加入倒排索引之前,Elasticsearch在其主体上的操作称为分析(analysis)。


而analysis的实现可以是Elasticsearch内置分词器(analyzer)或者是自定义分词器。


Analyzer的由如下三部分组成:

image.png

4.1 character filters 字符过滤

字符过滤器将原始文本作为字符流接收,并可以通过添加,删除或更改字符来转换字符流。


字符过滤分类如下:


HTML Strip Character Filter.

用途:删除HTML元素,如<b>,并解码HTML实体,如&amp 。


Mapping Character Filter

用途:替换指定的字符。


Pattern Replace Character Filter

用途:基于正则表达式替换指定的字符。


4.2 tokenizers 文本切分为分词

接收字符流(如果包含了4.1字符过滤,则接收过滤后的字符流;否则,接收原始字符流),将其分词。

同时记录分词后的顺序或位置(position),以及开始值(start_offset)和偏移值(end_offset-start_offset)。


tokenizers分类如下:


Standard Tokenizer

Letter Tokenizer

Lowercase Tokenizer

详细需参考官方文档。

4.3 token filters分词后再过滤

针对tokenizers处理后的字符流进行再加工,比如:转小写、删除(删除停用词)、新增(添加同义词)等。


是不是看着很拗口,甚至不知所云。


没关系,但,脑海中的这张三部分组成的图以及三部分的执行顺序一定要加深印象。


5、Elasticsearch自带的Analyzer

5.1 Standard Analyzer

标准分析器是默认分词器,如果未指定,则使用该分词器。

它基于Unicode文本分割算法,适用于大多数语言。


5.2 Whitespace Analyzer

基于空格字符切词。


5.3 Stop Analyzer

在simple Analyzer的基础上,移除停用词。


5.4 Keyword Analyzer

不切词,将输入的整个串一起返回。

更多分词器参考官方文档。


6、自定义分词器的模板

自定义分词器的在Mapping的Setting部分设置。


PUT my_custom_index

{

"settings":{

"analysis":{

"char_filter":{},

"tokenizer":{},

"filter":{},

"analyzer":{}

}

}

}

1

2

3

4

5

6

7

8

9

10

11

脑海中还是上面的三部分组成的图示。

其中:


“char_filter”:{},——对应字符过滤部分;

“tokenizer”:{},——对应文本切分为分词部分;

“filter”:{},——对应分词后再过滤部分;

“analyzer”:{}——对应分词器组成部分,其中会包含:1. 2. 3。

7、针对问题,实践一把

7.1 问题拆解

核心问题1:实际检索中,名字不带","。

逗号需要字符过滤掉。在char_filter阶段实现。


核心问题2:思考基于什么进行分词?

Li,LeiLei;Han,MeiMei;的构成中,只能采用基于“;"分词方式。


核心问题3:支持姓名颠倒后的查询。

即:LeileiLi也能被检索到。

需要结合同义词实现。


在分词后再过滤阶段,将:LiLeiLei和LeiLeiLi设定为同义词。


7.2 实践

基于问题的答案如下:


PUT my_index

{

 "settings": {

   "analysis": {

     "char_filter": {

       "my_char_filter": {

         "type": "mapping",

         "mappings": [

           ", => "

         ]

       }

     },

     "filter": {

       "my_synonym_filter": {

         "type": "synonym",

         "expand": true,

         "synonyms": [

           "lileilei => leileili",

           "hanmeimei => meimeihan"

         ]

       }

     },

     "analyzer": {

       "my_analyzer": {

         "tokenizer": "my_tokenizer",

         "char_filter": [

           "my_char_filter"

         ],

         "filter": [

           "my_synonym_filter"

         ]

       }

     },

     "tokenizer": {

       "my_tokenizer": {

         "type": "pattern",

         "pattern": "\\;"

       }

     }

   }

 },

 "mappings": {

   "_doc": {

     "properties": {

       "text": {

         "type": "text",

         "analyzer": "my_analyzer"

       }

     }

   }

 }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

7.3 analyze API的妙处

用途:


实际业务场景中,检验分词的正确性。

排查检索结果和预期不一致问题的利器。

用法1:直接验证分词结果。


GET my_index/_analyze

{

 "analyzer": "my_analyzer",

 "text":     "Li,LeiLei"

}

1

2

3

4

5

用法2:基于索引字段验证分词结果。


GET my_index/_analyze

{

 "field": "my_text",

  "text":     "Li,LeiLei"

}

1

2

3

4

5

8、小结

自定义分词这块,我认为不大好理解。光是:1)“char_filter”:2)“tokenizer” 3)“filter” 4)"analyzer"就很容易把人绕进去。

网上中文文档的各种翻译不完全一致,很容易误导,官方英文文档的解读会更准确。

要牢记图中三部分的组成,结合实际业务场景具体分析+实践会加深自定义分词的理解。

参考:

1、官方文档

2、rockybean教程

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
3月前
|
自然语言处理 大数据 应用服务中间件
大数据-172 Elasticsearch 索引操作 与 IK 分词器 自定义停用词 Nginx 服务
大数据-172 Elasticsearch 索引操作 与 IK 分词器 自定义停用词 Nginx 服务
85 5
|
3月前
|
自然语言处理 Java 网络架构
elasticsearch学习三:elasticsearch-ik分词器的自定义配置 分词内容
这篇文章是关于如何自定义Elasticsearch的ik分词器配置以满足特定的中文分词需求。
182 0
elasticsearch学习三:elasticsearch-ik分词器的自定义配置 分词内容
|
2月前
|
测试技术 API 开发工具
ElasticSearch的IK分词器
ElasticSearch的IK分词器
66 7
|
3月前
|
存储 JSON Java
elasticsearch学习一:了解 ES,版本之间的对应。安装elasticsearch,kibana,head插件、elasticsearch-ik分词器。
这篇文章是关于Elasticsearch的学习指南,包括了解Elasticsearch、版本对应、安装运行Elasticsearch和Kibana、安装head插件和elasticsearch-ik分词器的步骤。
283 0
elasticsearch学习一:了解 ES,版本之间的对应。安装elasticsearch,kibana,head插件、elasticsearch-ik分词器。
|
4月前
|
存储 自然语言处理 关系型数据库
ElasticSearch基础3——聚合、补全、集群。黑马旅游检索高亮+自定义分词器+自动补全+前后端消息同步
聚合、补全、RabbitMQ消息同步、集群、脑裂问题、集群分布式存储、黑马旅游实现过滤和搜索补全功能
|
5月前
|
JSON 自然语言处理 数据库
Elasticsearch从入门到项目部署 安装 分词器 索引库操作
这篇文章详细介绍了Elasticsearch的基本概念、倒排索引原理、安装部署、IK分词器的使用,以及如何在Elasticsearch中进行索引库的CRUD操作,旨在帮助读者从入门到项目部署全面掌握Elasticsearch的使用。
|
2月前
|
存储 安全 数据管理
如何在 Rocky Linux 8 上安装和配置 Elasticsearch
本文详细介绍了在 Rocky Linux 8 上安装和配置 Elasticsearch 的步骤,包括添加仓库、安装 Elasticsearch、配置文件修改、设置内存和文件描述符、启动和验证 Elasticsearch,以及常见问题的解决方法。通过这些步骤,你可以快速搭建起这个强大的分布式搜索和分析引擎。
68 5
|
4月前
|
NoSQL 关系型数据库 Redis
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
mall在linux环境下的部署(基于Docker容器),docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongodb、minio详细教程,拉取镜像、运行容器
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
|
5月前
|
数据可视化 Docker 容器
一文教会你如何通过Docker安装elasticsearch和kibana 【详细过程+图解】
这篇文章提供了通过Docker安装Elasticsearch和Kibana的详细过程和图解,包括下载镜像、创建和启动容器、处理可能遇到的启动失败情况(如权限不足和配置文件错误)、测试Elasticsearch和Kibana的连接,以及解决空间不足的问题。文章还特别指出了配置文件中空格的重要性以及环境变量中字母大小写的问题。
一文教会你如何通过Docker安装elasticsearch和kibana 【详细过程+图解】
|
5月前
|
Ubuntu Oracle Java
如何在 Ubuntu VPS 上安装 Elasticsearch
如何在 Ubuntu VPS 上安装 Elasticsearch
65 0