Elasticsearch 分析器(内置分析器,自定义分析器,IK分析器)
- 内置分析器
- 使用分析器
- 自定义分析器
- 中文分析器(IK分析器)
- 安装
- 使用
- 添加词典
内置分析器
官网:https://www.elastic.co/guide/en/elasticsearch/reference/7.10/analysis-analyzers.html
ES 内置了一些分析器。
默认情况下,一个索引的字段类型为text是,该字段在建立索引时和查询时的分析器时standard。
standard分析器由standard分词器,lowercase分词过滤器和stop分词过滤器(默认禁用)构成。
standard分析器对于中文只能按字拆分。
# 默认的标准分析器
POST _analyze
{"analyzer": "standard","text": "<h>This is a word"
}
# 自己组合的分析器,
# 字符过滤器过滤 html标签
# 分词器,根据空白符进行分词
# 分词过滤器,字母小写 并 过滤掉停用词
POST _analyze
{"char_filter": ["html_strip"], "tokenizer": "whitespace","filter": ["lowercase","stop"], "text": "<h>This is a word"
}
解释上述结果
原文: <h>This is a word
经过html字符过滤器 This is a word
经过空白符分词器 [This, is, a, word]
经过小写分词器 [this, is , a, word]
经过停用词分词器 [word]
所以最终结果 只有 word 一个单词
使用分析器
PUT /my-index-000001
{//指定默认分析器为whitespace"settings": {"analysis": {"analyzer": {"default":{"type":"whitespace"}}}},"mappings": {"properties": {// 没有指定分析器,搜索和索引都使用默认分析器whitespace"title1":{"type": "text"},// 仅指定索引分析器standard,搜索和索引都使用分析器standard"title2":{"type": "text","analyzer": "standard"},// 分别指定索引分析器和搜索分析器,索引分析器为standard,搜索分析器为standard"title3":{"type": "text","analyzer": "standard","search_analyzer": "standard"}}}
}
注意: 上述 title3 指定的搜索分析器和索引时的分析器是一致的,但是在大多数情况下是没有必要指定的,因为在默认情况下二者就是一致的。
如果指定的搜索分析器和索引时的分析器不一致,则ES在搜索时可能出现有不符合预期的匹配情况,因此该设置在使用时需要慎重选择。
自定义分析器
ES 也支持用户自定义分析器
当自带的分析器不满足需求时,需要用户自己定义分析器
PUT my-index-000002
{"settings": {"analysis": {"analyzer": {"my_custom_analyzer": { //指定 自定义类型分析器"type": "custom",//指定 自定义的字符过滤器"char_filter": ["my_filter"],// 指定 自定义的分词器"tokenizer": "my_tokenizer",// 指定 自定义的 分词过滤器"filter": ["lowercase","my_filter"]}},//自定义的分词器"tokenizer": {// 分词器:按照正则进行切分词"my_tokenizer": { "type": "pattern","pattern": "[ .,!?]"}},// 自定义的 字符过滤器"char_filter": {// 字符过滤器:将:) 转化为 _happy_,将:( 转化为 _sad_"my_filter": { "type": "mapping","mappings": [":) => _happy_",":( => _sad_"]}},// 自定义的 分词过滤器"filter": {// 分词过滤器,过滤英文的停用词"my_filter": { "type": "stop","stopwords": "_english_"}}}}
}POST my-index-000002/_analyze
{"analyzer": "my_custom_analyzer","text": "I'm a :) person, and you?"
}
解释上述结果:
原文: I’m a : ) person, and you?
经过my_filter字符过滤器 I’m a happy person, and you?
经过my_tokenizer分词器 [I’m, a, happy, person, and, you]
经过小写分词器 [i’m, a, happy, person, and, you]
经过停用词分词器 删除 停用词(a, and) [i’m, happy, person, you]
所以最终结果 [i’m, happy, person, you]
中文分析器(IK分析器)
前面提到过,ES内置的分词器都不支持中文的分词。所以我们需要自己安装中文分析器插件。
IK分析器时比较常用的中文分析器。其原理是基于词典的分词算法。
安装
下载地址: https://github.com/medcl/elasticsearch-analysis-ik/releases
下载与ES版本一致的IK插件包,这里以7.10.2 为例
# 进入es的插件目录
cd es/plugins
# 创建ik目录
mkdir ik
# 在ik 目录下解压 ik分析器
unzip elasticsearch-analysis-ik-7.10.2.zip
# 进入es/bin目录,重启es
./elasticsearch -d
使用
IK分词器内置了两个子分析器,即ik_smart 和 ik_max_word (分词器与其同名)
ik_smart:切分粒度比较粗
例如: “假日酒店”=> “假日酒店”
POST _analyze
{"analyzer": "ik_smart","text": "假日酒店"
}
ik_max_word: 切分粒度比较细,穷举了所有可能的组合
例如: “假日酒店”=> “假日酒店”,“假日”,“酒店”
POST _analyze
{"analyzer": "ik_max_word","text": "假日酒店"
}
添加词典
对于IK分词器不认识的词,其不能合理切分,所以有时需要我们手动添加一些词典。
例如:一些网络热词,ik分词器并不能很好的切分
POST _analyze
{"analyzer": "ik_smart","text": "及你太美"
}
上面的分词结果,显然不是我想要的。为了得到正确的分词结果。需要添加自定义词典
IK分词器提供了两种自定义词典方式
- 本地
- 远程
进入ik 分析器 config 目录
编辑 IKAnalyzer.cfg.xml 可以实现自定义词典
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties><comment>IK Analyzer 扩展配置</comment><!--用户可以在这里配置自己的扩展字典 --><entry key="ext_dict">custom-dict.dic</entry><!--用户可以在这里配置自己的扩展停止词字典--><entry key="ext_stopwords">custom-stop.dic</entry><!--用户可以在这里配置远程扩展字典 --><!-- <entry key="remote_ext_dict">words_location</entry> --><!--用户可以在这里配置远程扩展停止词字典--><!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
在 custom-dict.dic 文件中 写入 所需的热词,
重启ES,重新分析,可以看到热词按照自定义设置进行切分了
POST _analyze
{"analyzer": "ik_smart","text": "及你太美"
}
如果还需要其他的热词更新方式,如Mysql,Redis 等,可以下载Ik分析器的源码自行开发
注意: 默认情况下,IK分词器不会热更新词库,也就是说,每次更新自定义词库,都需要重启ES。同样的,想要热更新,可以下载源码自行开发。