【Elasticsearch教程19】IK分词器 ik_max_word、ik_smart
通过上表,可以看出在好处是保存文档时,已经索引尽可能多的词,而在搜索文档时,没有必要对搜索关键字拆分的很细,这样提高了查询的效率。安装IK分词器的教程网上太多了,我这里就不再赘述了。全民制作人,大家好,我是练习时长2年半的个人练习生亚瑟王,喜欢ES、钢琴、鼓励队友。分词器对中文不友好,会将中文分割成一个个汉字。IK分词器的作者对这个项目维护的比较积极,能紧跟ES的最新版本。这1个词条,直接拿"亚瑟
一、IK分词器
全民制作人,大家好,我是练习时长2年半的个人练习生亚瑟王,喜欢ES、钢琴、鼓励队友。
ES默认的standard分词器对中文不友好,会将中文分割成一个个汉字。对于中文分词,目前比较常用的是IK分词器。IK分词器的作者对这个项目维护的比较积极,能紧跟ES的最新版本。
安装IK分词器的教程网上太多了,我这里就不再赘述了。本篇博客仅仅记录我自己学习IK的一些小小心得。
1. 创建测试的Mapping和数据
name的analyzer是默认的standard,对于姓名这样的中文,适合用standard,因为姓名中一般没有固定的词组。word的analyzer是ik_max_word,search_analyzer是ik_smart
PUT pigg_test_ik
{
"mappings":{
"properties":{
"name":{
"type":"text",
"analyzer":"standard"
},
"word":{
"type":"text",
"analyzer":"ik_max_word",
"search_analyzer":"ik_smart"
}
}
}
}
插入测试数据
PUT pigg_test_ik/_doc/1
{
"name": "亚瑟王",
"word": [
"亚瑟王爱弹琴"
]
}
2. 查看文档如何存储
执行如下命令,看字符串是如何拆分后索引的
GET pigg_test_ik/_doc/1/_termvectors?fields=name
GET pigg_test_ik/_doc/1/_termvectors?fields=word
| 字段 | 词条 |
|---|---|
| name | 亚、瑟、王 |
| word | 亚瑟、王、亚瑟王、爱、弹琴 |
3. 在name上match查询
- 因为name是
"analyzer":"standard",所以搜索的关键词会拆成一个个独立的字。 - 只要关键词中包含
亚、瑟、王中任意一个字,都算匹配成功。
GET pigg_test_ik/_search
{
"query": {
"match": {
"name": "i瑟" //拆成"i"和"瑟","瑟"命中文档
}
}
}
- 但是如果修改
match的operator为and,则需要所有字全部命中
GET pigg_test_ik/_search
{
"query": {
"match": {
"name": {
"query": "i瑟", //因为有"i",所以没有匹配到文档
"operator": "and"
}
}
}
}
4. 在word上match查询
在word字段上为啥analyzer是ik_max_word,而search_analyzer是ik_smart呢?
ik_max_word会尽可能拆分出更多的词条组合ik_smart则相对智能,不会拆的很细
我们先来看下这2个分析器对亚瑟王爱弹琴是如何处理的。
POST pigg_test_ik/_analyze
{
"analyzer": "ik_smart",
"text": "亚瑟王爱弹琴"
}
POST pigg_test_ik/_analyze
{
"analyzer": "ik_max_word",
"text": "亚瑟王爱弹琴"
}
| analyzer | 词条 |
|---|---|
| ik_smart (搜索时) | 亚瑟王、爱、弹琴 |
| ik_max_word (索引时) | 亚瑟、王、亚瑟王、爱、弹琴 |
通过上表,可以看出在好处是保存文档时,已经索引尽可能多的词,而在搜索文档时,没有必要对搜索关键字拆分的很细,这样提高了查询的效率。
"亚瑟王"会拆分成"亚瑟王"这1个词条,直接拿"亚瑟王"去匹配文档,可以匹配成功
GET pigg_test_ik/_search
{
"query": {
"match": {
"word": "亚瑟王" //会拆分成"亚瑟王"这1个词条,直接拿"亚瑟王"去匹配文档,可以匹配成功
}
}
}
"瑟王"会拆分成"瑟"和"王"这2个词条,"瑟"这个字匹配不到文档,但是"王"这个字可以匹配到文档
GET pigg_test_ik/_search
{
"query": {
"match": {
"word": "瑟王" //会拆分成"瑟"和"王"这2个词条,"瑟"这个字匹配不到文档,但是"王"这个字可以匹配到文档
}
}
}
使用如下命令解释为何"瑟王"能匹配到文档
GET pigg_test_ik/_explain/1
{
"query": {
"match": {
"word": "瑟王"
}
}
}
返回结果中显示如下:
"description" : "weight(word:王 in 1) [PerFieldSimilarity], result of:",
说明是"王"这个字匹配到文档的。
5. 自定义字典
在ik的config目录下创建ext.dic文本文件,添加一些自定义的扩展词
修改如下的配置文件,指定扩展字典的文件名
上面操作执行好了后,一定要重启ES,否则是不生效的。
更多推荐



所有评论(0)