一、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,否则是不生效的。