ElasticSearch中文分词
1. 内置分词器解析
Elasticsearch模糊查询这么快,是因为采用了倒排索引,而倒排索引的核心就是分词,把text格式的字段按照分词器进行分词并编排索引。
为了发挥自己的优势,Elasticsearch已经提供了多种功能强大的内置分词器。
1.1 内置分词器梳理
对Elasticsearch提供的内置分词器的作用进行如下总结:
分词器 | 作用 |
---|---|
Standard | ES默认分词器,按单词分类并进行小写处理 |
Simple | 按照非字母切分,然后去除非字母并进行小写处理 |
Stop | 按照停用词过滤并进行小写梳理,停用词包括the、a、is |
Whitespace | 按照空格切分 |
Language | 据说提供了30多种常见语言的分词器 |
Pattern | 按照正则表达式进行分词,默认是\W+ ,代表非字母 |
Keyword | 不进行分词,作为一个整体输出 |
可以看到,这些内置分词器擅长处理单词和字母。索引如果要处理的是英文数据的话,它们的功能可以说已经很全面了。
1.2 内置分词器对中文的局限性
这里使用的es和kibana版本都是7.8.1
1、首先创建一个索引,并批量插入一些包含中文和英文的数据:
# 创建索引
PUT /bjytest
{
"settings": {
"number_of_shards": "2",
"number_of_replicas": "0"
}
}
# 批量插入数据
POST _bulk
{ "create" : { "_index" : "bjytest", "_id" : "1001" } }
{"id":1,"name": "白居不易","hobby": "music and movie"}
{ "create" : { "_index" : "bjytest", "_id" : "1002" } }
{"id":2,"name": "好好学习","hobby": "music"}
{ "create" : { "_index" : "bjytest", "_id" : "1003" } }
{"id":3,"name": "天天向上","hobby": "movie"}
{ "create" : { "_index" : "bjytest", "_id" : "1004" } }
{"id":4,"name": "白居_不易","hobby": "run"}
2、使用 term 查询匹配数据,分别对比中文英文:
首先查询“hobby"包含”music“的数据,根据录入顺序,应该返回的是前两条:
POST /bjytest/_search
{
"query": {
"term": {
"hobby":"music"
}
}
}
可以看到,结果符合预期。所以在英文词汇下,即便是默认的分词器Standard也够用了。
然后再查找一下"name"包含”不易“的数据,按照录入顺序,应该返回第一条和第四条:
POST /bjytest/_search
{
"query": {
"term": {
"name":"不易"
}
}
}
可以看到, 查询中文词汇没有匹配到的数据。
问题:为什么在默认分词器下,不能查找到词汇呢?
因为词汇是由多个汉字组成的,不像英文,一个词汇就是一个单词,比如”music“ 对应音乐,汉字需要两个字才可以表示。而内置分词器是没有考虑到这类情况的,所以它们切分汉字时就会全部切分成单个汉字了,因此找不到”不易“相关的数据,但应该可以找到”不“相关的数据。
查找”name“包含”不“的数据:
POST /bjytest/_search
{
"query": {
"term": {
"name":"不"
}
}
}
如果想匹配到某条数据而不想让它分词,需要使用keyword,这样对应的text就会作为一个整体来查询:
POST /bjytest/_search
{
"query": {
"term": {
"name.keyword":"白居_不易"
}
}
}
3、便捷分词器测试技巧
其实测试分词器对词汇的分词,有一个更简便的方法,就是利用 Elasticsearch 的 _analyze
,比如想看:“白居不易” 被默认分词器 standard 分词后的效果,只需要执行如下代码:
POST /_analyze
{
"analyzer": "standard",
"text": "白居不易"
}
2. IK分词器
2.1 安装IK分词器
下载地址:https://github.com/medcl/elasticsearch-analysis-ik/releases
1、访问下载地址,找到对应的版本(7.8.1)
2、下载好之后,在安装好的elasticsearch的plugins 目录下新建文件夹 analysis-ik ,然后将下载好的文件解压到此目录中;将analysis-ik 中的config 文件夹拷贝到ES的config目录下的ik文件夹(自己创建)。
3、重启es,看 启动日志中日否有IK
4、使用下IK分词器,看能否正常使用
POST /_analyze
{
"analyzer": "ik_smart",
"text": "白居不易"
}
2.2 使用
根据官方的建议,ik 分词器的名字可以使用:ik_smart
,ik_max_word
Analyzer:
ik_smart
,ik_max_word
Tokenizer:
ik_smart
,ik_max_word
测试分词区别
1、通过ik_smart
来对”中华人民共和国“进行分词
POST /_analyze
{
"analyzer": "ik_smart",
"text": "中华人民共和国"
}
2、通过ik_max_word
来对”中华人民共和国“进行分词
POST /_analyze
{
"analyzer": "ik_max_word",
"text": "中华人民共和国"
}
由以上对比可见:
- ik_max_word:会将文本做最细粒度的拆分
- ik_smart:会做最粗粒度的拆分。