Analysis和Analyzer
Analysis :文本分析是把全文本转换一系列单词(term/token)的过程,也叫分词(Analyzer)。Analysis是通过Analyzer来实现的。分词就是将文档通过Analyzer分成一个一个的Term,每一个Term都指向包含这个Term的文档。
Analyzer 组成
- 在ES中默认使用标准分词器:StandardAnalyzer 特点:中文单字分词,英文单词分词我是 good man -> 我 是 good man
分词器由三种构件组成的:character filters,tokenizers,token filters
character filters
字符过滤器
- 在一段文本进行分词之前,先进行预处理,比如常见的过滤html标签(
<span>cfd<span>
-> cfd) - 将一些相似的词进行转换(比如
&
->and
)
tokenizers
分词器
- 英文单词可以根据空格将单词分隔开,中文分词比较复杂,可以采用机器学习算法来分词
token filters
Token过滤器
- 将切分的单词进行加工。大小写转换(将”Cfd“转为小写,搜索也会转化),去掉停用词(例如”a“, "and", "the"这种很少搜索的词,但是出现次数很多),加入同义词(例如“jump”和“leap”) 注意:
- 三者的顺序:character filters -> tokenizers -> token filters
- 三者个数:character filters(0个或多个) + tokenizers + token filters(0个或多个)
内置分词器
- Standard Analyzer - 默认分词器,英文按单词词切分,并小写处理
- Simple Analyzer - 按照单词切分(符号被过滤),小写处理
- Stop Analyzer - 小写处理,停用词过滤(the,a,is)
- whitespace Analyzer - 按照空格切分,不转小写
- Keyword Analyzer - 不分词,直接将输入当作输出
内置分词器测试
- 标准分词器
- 特点:按照单词分词 英文统一转为小写 过滤标点符号 中文单字分词
bash
复制代码
POST /_analyze { "analyzer":"standard", "text":"我是CFD,very good person" }
- Simple 分词器
- 特点:按照单词分词 英文统一转换为小写 去掉符号 中文按照空格进行分词
bash
复制代码
POST /_analyze { "analyzer":"simple", "text":"我是CFD ,very good person" }
- Whitespace 分词器
- 特点:中文英文按照空格分词 英文不会转为小写 不去掉标点符号
bash
复制代码
POST /_analyze { "analyzer":"whitespace", "text":"我是CFD ,very good person" }
创建索引同时设置分词器
json
复制代码
PUT /test { "mappings": { "properties": { "title":{ "type": "text", "analyzer": "keyword" } } } }
中文分词器
使用IK分词器medcl/elasticsearch-analysis-ik: The IK Analysis plugin integrates Lucene IK analyzer into elasticsearch, support customized dictionary. (github.com)因为github上使用的是8.10.4,并且没有8.10.2的版本,所以我修改了以下版本号 修改方法见连接Elasticsearch 8.X 分词插件版本更新不及时解决方案-CSDN博客
- ik_smart:会做最粗粒度的拆分
bash
复制代码
POST /_analyze { "analyzer":"ik_smart", "text":"中华人民共和国国歌" }
json
复制代码
{ "tokens": [ { "token": "中华人民共和国", "start_offset": 0, "end_offset": 7, "type": "CN_WORD", "position": 0 }, { "token": "国歌", "start_offset": 7, "end_offset": 9, "type": "CN_WORD", "position": 1 } ] }
- ik_max_word:会见文本做最细粒度的拆分
bash
复制代码
POST /_analyze { "analyzer":"ik_max_word", "text":"算法设计与分析基础" }
json
复制代码
{ "tokens": [ { "token": "中华人民共和国", "start_offset": 0, "end_offset": 7, "type": "CN_WORD", "position": 0 }, { "token": "中华人民", "start_offset": 0, "end_offset": 4, "type": "CN_WORD", "position": 1 }, { "token": "中华", "start_offset": 0, "end_offset": 2, "type": "CN_WORD", "position": 2 }, { "token": "华人", "start_offset": 1, "end_offset": 3, "type": "CN_WORD", "position": 3 }, { "token": "人民共和国", "start_offset": 2, "end_offset": 7, "type": "CN_WORD", "position": 4 }, { "token": "人民", "start_offset": 2, "end_offset": 4, "type": "CN_WORD", "position": 5 }, { "token": "共和国", "start_offset": 4, "end_offset": 7, "type": "CN_WORD", "position": 6 }, { "token": "共和", "start_offset": 4, "end_offset": 6, "type": "CN_WORD", "position": 7 }, { "token": "国", "start_offset": 6, "end_offset": 7, "type": "CN_CHAR", "position": 8 }, { "token": "国歌", "start_offset": 7, "end_offset": 9, "type": "CN_WORD", "position": 9 } ] }
扩展词和停用词配置
IK支持自定义扩展词典和停用词典
- 扩展词典就是有些词并不是关键词,但是也希望被ES用来作为检索的关键词,可以将这些词加入扩展词曲。例如姓名,默认还是单字,但是希望作为关键字
- 停用词典就是有些词是关键词,但是出于业务场景不想使用这些关键词被检索到,可以将这些词放入停用词典。例如介词等
- 定义扩展词典和停用词典可以修改lK分词器中
config
目录中IKAnalyzer.cfg.xml
这个文件。
- 修改vim IKAnalyzer.cfg.xml
xml
复制代码
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE properties sYSTEM "http:/ljava.sun.com/dtd/properties.dtd"> <properties> <comment>IK Analyzer扩展配置</comment><!--用户可以在这里配置自己的扩展字典--> <entry key="ext_dict">ext_dict.dic</entry><!--用户可以在这里配置自己的扩展停止词字典--> <entry key="ext_stopwords">ext_stopword.dic</ entry> </properties>
- 在ik分词器目录下config目录中创建ext_dict.dic文件 编码一定要为UTF-8才能生效 vim ext_dict.dic 加入扩展词即可
bash
复制代码
POST /_analyze { "analyzer":"ik_smart", "text":"常凤迪" }
json
复制代码
{ "tokens": [ { "token": "常凤迪", "start_offset": 0, "end_offset": 3, "type": "CN_WORD", "position": 0 } ] }
- 在ik分词器目录下config目录中创建ext_stopword.dic文件 vim ext_stopword.dic 加入停用词即可
- 重启ES生效