elasticsearch 默认分词器为
standard分词器,即:不指定分词器默认使用standard分词器
修改默认分词器:
PUT index
{
"settings":{
"analysis":{
"analyzer":{
"caseSensitive":{
"filter":"lowercase",
"type":"custom",
"tokenizer":"keyword"
}
}
}
},
"index.analysis.analyzer.default.type":"ik_smart"
}
index.analysis.analyzer.default.type为修改默认词器 ik_smart为ik分词器的一种分词模式。
settings为设置,上面设置是忽视大小写查询。
index只允许在创建的时候修改,所以尽可能把需要配置的地方提前准备好,免得日后修改还要备份数据等,麻烦。
写分词
设置默认分词器以后,往索引里面添加文档时会使用默认分词器将文档中的字段分词(keyword及一些不分词器类型除外)。然后索引中存的就是分词后的结果。
默认standard分词器会将中文全部分成一个个的字符,ik_smart为比较好用的分词器,拥有中心词库。
读分词
读分词默认使用默认分词器进行分词,将搜索词条进行分词,然后去文档匹配,根据得分排序。
读分词可以指定分词器
post index/_search
{
"query":{
"match": {
"goods_serial": {
"analyzer": "ik_smart",
"query": "xxxx"
}
}
}
}
部分搜索无法指定分词器,比如 match_phrase_prefix、term等,
也就是可以写入用默认分词器,读使用指定分词器。
不分词
所有存入mapping的字段默认添加一个feild.keyword字段。使用feild.keyword字段进行搜索将不进行分词。
使用feild.keyword字段进行搜索时不仅不分词,而且大小写匹配设置也是没有用的(就是设置了忽视大小写查询,但是查询依旧不能忽视大小写)。
默认使用ik_smart的同学要注意了,ik_smart 在写入时会将词分为词段来存放:
王者荣耀->“王者”,”荣耀“
使用"王者"搜索时读
王者->“王者”
匹配上。
但是写入一些词汇时会进行有问题
乳胶手套->“乳胶手套”
ik_smart 将匹配到中心词库 “乳胶手套” 则将"乳胶手套" 作为一个单词写入
搜索 ”手套“
读
”手套“ ->”手套“
则无法匹配
这边建议在写入时指定默认分词器为ik_max_word,会最小粒度的划分为单个词汇,ik_smart会分为大粒子词汇:
{
"tokens": [
{
"token": "乳胶手套",
"start_offset": 0,
"end_offset": 4,
"type": "CN_WORD",
"position": 0
}
]
}
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": 0,
"end_offset": 1,
"type": "CN_WORD",
"position": 2
},
{
"token": "胶",
"start_offset": 1,
"end_offset": 2,
"type": "CN_WORD",
"position": 3
},
{
"token": "手套",
"start_offset": 2,
"end_offset": 4,
"type": "CN_WORD",
"position": 4
},
{
"token": "套",
"start_offset": 3,
"end_offset": 4,
"type": "CN_WORD",
"position": 5
}
]
}
所以使用ik_max_word将写入文档尽可能划分为最小颗粒,搜索时可以使用ik_smart。
另外ik分词器的ik_smart对于一些比较偏门的中文词条,比如化学用品等可能不会进行分词
所以一个文档的搜索得分很低,甚至有可能不显示。在读写均使用ik_max_word的情况下会就是ik_smart+standard分词的合集然后加一点比较细的词汇,所以搜索结果会很杂乱。
在这里只建议大家使用ik_max_word写入+ik_smart搜索,若只是要完全包含词条,建议使用wildcard+feild.keyword查询,可以不设置分词器。