1、简介
分词就是将一段文本按照一定的规则切分成以一个一个的关键字的过程
ElasticSearch的分词器(Analyzer)一般由三种组件构成:
1、character filter 字符过滤器:
在一段文本分词之前,先进行预处理,最常见的就是【过滤html标签】
例如:<span>hello<span> --> hello,I & you --> I and you
2、tokenizers 分词器:
默认情况下,英文分词根据空格将单词分开;中文分词按单字隔开,也可以采用机器学习算法来分词
3、Token filters Token过滤器:
将切分的单词进行加工,大小写转换,去掉停用词(例如“a”、“and”、“the”等等 ),加入同义词(例如同义词像“jump”和“leap”)
三者顺序:Character Filters—>Tokenizer—>Token Filter
三者个数:Character Filters(0个或多个) + Tokenizer + Token Filters(0个或多个)
创建索引时设置分词器
PUT /my_index
{
"mappings": {
"properties": {
"title":{
"type": "text",
"analyzer": "standard" #显示指定分词器
}
}
}
}
2、常见内置分词器
注意:按照什么分词就会去掉什么 !!!!!
标准分词器(standard analyzer)默认分词器
- 英文按照单词、符号(逗号、句号、包括空格等等)分词,英文统一转为小写;
- 中文单字分词;
GET _analyze
{
"analyzer": "standard",
"text": "hello world,I'm Chinese1我爱中国,我是中国人。"
}
#分词的结果
hello|world|i'm|chinese1|我|爱|中|国|我|是|中|国|人
简单分词器(simple analyzer)
- 英文按照单词、符号(逗号、句号、包括空格等等)、数字分词,英文统一转为小写;
- 中文按照符号(逗号、句号、包括空格等等)、数字进行分词;
GET _analyze
{
"analyzer": "simple",
"text": "hello world,I'm Chinese1我爱中国,我是中国人。"
}
#分词的结果
hello|world|i|m|chinese|我爱中国|我是中国人
空白分词器(whitespace analyzer)
- 中文和英文都按照空格分词 ,英文不会转为小写;
GET _analyze
{
"analyzer": "whitespace",
"text": "hello world,I'm Chinese1我爱中国,我是中国人。"
}
#分词的结果
“hello|world,I'm|Chinese1我爱中国,我是中国人。
停止分词器(stop analyzer)
- 英文按照符号(逗号、句号、包括空格等等)、数字、介词|冠词(the、to、a、an、this等)分词;
- 中文按照符号(逗号、句号、包括空格等等)、数字分词,但是中文的介词|冠词分词,也不会切割为一个一个的汉字;
GET _analyze
{
"analyzer": "stop",
"text" : "so whenever we visit a Chinese family she tells me to buy them a gift.hello1我爱中国,我是中国人。"
}
#分词的结果
so|whenever|we|visit|Chinese|family|she|tells|me|buy|them|gift|hello|我爱中国|我是中国人
正则表达式分词器(pattern analyzer)
- 根据正则表达式来切,默认使用的正则表达式是\W+,在匹配\W+的地方切。
\w包括英文字母、阿拉伯数字、_,\W是任意一个非\w字符,中文字符也算\W。
+表示一个及以上,就是说多个非\w字符算作一处。
语言分词器(language analyzer)
- 提供了 30 多种常见语言的分词器,把语言全小写就是,比如english,chinese。
english、chinese的效果都一样:在空格、符号、英文介词|冠词 处切,中文切割为一个一个的汉字。
其他分词器
- Keyword Analyzer - 不分词,直接将输入当做输出
- Customer Analyzer - 自定义分词器
3、中文分词器
在ES中支持中文分词器非常多 如 smartCN、IK 等,推荐的就是 IK分词器。
1、安装IK 参考我原来的文章
2、IK使用
IK分词器有两种粒度划分:
- ik_smart: 会做最粗粒度的拆分
- ik_max_word: 会将文本做最细粒度的拆分
POST /_analyze
{
"text":"中华民族共和国国歌",
"analyzer":"ik_smart"
}
{
"tokens" : [
{
"token" : "中华民族",
"start_offset" : 0,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "共和国",
"start_offset" : 4,
"end_offset" : 7,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "国歌",
"start_offset" : 7,
"end_offset" : 9,
"type" : "CN_WORD",
"position" : 2
}
]
}
POST /_analyze
{
"text":"中华民族共和国国歌",
"analyzer":"ik_max_word"
}
{
"tokens" : [
{
"token" : "中华民族",
"start_offset" : 0,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "中华",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "民族",
"start_offset" : 2,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "共和国",
"start_offset" : 4,
"end_offset" : 7,
"type" : "CN_WORD",
"position" : 3
},
{
"token" : "共和",
"start_offset" : 4,
"end_offset" : 6,
"type" : "CN_WORD",
"position" : 4
},
{
"token" : "国",
"start_offset" : 6,
"end_offset" : 7,
"type" : "CN_CHAR",
"position" : 5
},
{
"token" : "国歌",
"start_offset" : 7,
"end_offset" : 9,
"type" : "CN_WORD",
"position" : 6
}
]
}
扩展词和关键词
- 扩展词:就是有些词并不是关键词,但是也希望被ES用来作为检索的关键词,可以将这些词加入扩展词典
- 停用词:就是有些关键词,我们并不想让他被检索到,可以放入停用词典中
设置扩展词典和停用词典在es容器中的config
目录下的IKAnalyzer.cfg.xml中
- 修改vi 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">ext_dict.dic</entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords">ext_stopword.dic</entry>
</properties>
-
在es容器中
config
目录下中创建ext_dict.dic文件 编码一定要为UTF-8才能生效
vim ext_dict.dic 加入扩展词即可 -
在es容器中
config
目录中创建ext_stopword.dic文件
vim ext_stopword.dic 加入停用词即可 -
重启es生效
es本身也提供了一些常用的扩展词典和停用词典可以直接使用:
配置自定义远程扩展字典和停用词典参考