Elasticsearch synonym_graph同义词过滤器返回非预期结果问题排查
问题根因
1. 错误在索引阶段使用synonym_graph过滤器
synonym_graph是专门为查询阶段设计的过滤器,用来正确处理多词同义词的位置偏移,避免短语匹配失效。如果将它用在索引阶段的分析器中,Elasticsearch会自动将其降级为普通synonym过滤器,并且会把多词同义词规则强制拆分为单个词的同义映射:
你配置的Human Resources, HR会被拆解为:
- Human ↔ HR
- Resources ↔ HR
这就导致所有包含HR的文档在索引时都会被写入Human、Resources两个额外的词元,你搜索Resources自然会匹配到所有含HR的文档,这是得到非预期结果的核心原因。
2. 过滤器执行顺序错误
你当前的过滤器顺序是[graph_synonyms, lowercase],同义词匹配严格大小写敏感,应该先把所有词元转成小写,再执行同义词匹配,否则如果出现分词结果和同义词规则大小写不一致的情况,会导致同义词匹配失效。
修正方案
修改索引配置,给title字段分别配置索引时分析器和查询时分析器,仅在查询阶段使用synonym_graph:
{ "settings": { "number_of_shards": 1, "number_of_replicas": 0, "analysis": { "analyzer": { "index_synonym": { "tokenizer": "whitespace", "filter": [ "lowercase" ] }, "search_synonym": { "tokenizer": "whitespace", "filter": [ "lowercase", "graph_synonyms" ] } }, "filter": { "graph_synonyms": { "type": "synonym_graph", "synonyms_path": "/usr/share/elasticsearch/config/synonym.txt" } } } }, "mappings": { "dynamic": "strict", "properties": { "id": { "type": "keyword" }, "title": { "type": "text", "analyzer": "index_synonym", "search_analyzer": "search_synonym" }, "seniority": { "type": "keyword" }, "status": { "type": "keyword" } } } }
验证方式
修改配置重建索引后,可以用_analyze接口验证分词结果是否符合预期:
// 验证索引时分词,HR只会得到hr一个词元 POST /你的索引名/_analyze { "analyzer": "index_synonym", "text": "HR" } // 验证查询时分词,搜索HR会同时生成hr、human、resources三个词元匹配对应文档 POST /你的索引名/_analyze { "analyzer": "search_synonym", "text": "HR" }
配置后搜索Resources只会匹配到实际包含Human Resources或者直接包含Resources的文档,不会再匹配到仅含HR的文档。
内容的提问来源于stack exchange,提问作者Parth
相关产品推荐
相关产品推荐

