众所周知,es自带有同义词典功能,只需要在创建mappings的时候,指定同义词分词器地址,即可让底层同义词生效使用,简单快捷。下面说一说简单快捷背后隐藏的问题
一、创建同义词分词器
以下是创建一个简单的es索引,字段名是text,分别使用到了停用词典和同义词典,底层使用ik分词
PUT news
{
"mappings": {
"news": {
"properties": {
"text": {
"type": "text",
"analyzer": "text_complex_index",
"search_analyzer": "text_complex"
}
}
}
},
"settings": {
"index": {
"number_of_shards": "2",
"analysis": {
"filter": {
"pinyin_filter": {
"keep_joined_full_pinyin": "true",
"lowercase": "true",
"keep_original": "true",
"keep_first_letter": "false",
"keep_separate_first_letter": "false",
"type": "pinyin",
"limit_first_letter_length": "16",
"keep_full_pinyin": "false"
},
"stop_filter": {
"ignore_case": "true",
"type": "stop",
"stopwords_path": "stopwords.txt"
},
"synonym_filter": {
"ignore_case": "true",
"expand": "true",
"type": "synonym",
"synonyms_path": "synonyms.txt"
}
},
"analyzer": {
"text_complex": {
"filter": [
"stop_filter",
"synonym_filter",
"lowercase"
],
"type": "custom",
"tokenizer": "ik_smart"
},
"text_complex_index": {
"filter": [
"pinyin_filter",
"stop_filter",
"synonym_filter",
"lowercase"
],
"type": "custom",
"tokenizer": "ik_max_word"
}
}
},
"number_of_replicas": "1"
}
}
}
说明:
synonyms_path和stopwords_path为指定词典的相对位置,相对于es/config的位置
二、添加同义词
修改配置文件synonyms.txt,格式如下
三、是同义词词典生效
同义词不同于ik强词表,ik强词表修改后(非热更新),必须重启es集群,并且重新reindex,强词可以在ik分词的时候生效
同义词只需要对index进行reopen操作即可
# 关闭索引
POST _all/_close
# 开启索引
POST _all/_open
注意:
_all是这对es中所有索引生效的,慎用!!!
建议每次针对单个索引进行操作
四、同义词未生效(待补充)
原因一:同义词在ik层分词,并没有分出来
比如:“北大” 和 “北京大学” 是同义词,“北大” 并不在ik的强词典中。导致检索“北大” 的时候,分词成了“北”、“大”,并没有命中配置同义词(当然也是可以检索出“北京大学”相关数据的),导致es计算tfidf的时候出现偏差(影响排序和高亮显示)。
解决1:在ik底层添加“北大”、“北京大学”作为强词典,重启es集群,reindex
解决2:同义词放在检索的上一层,即检索“北大”时,同时检索“北京大学”