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。同样的,想要热更新,可以下载源码自行开发。