Elasticsearch DSL通配符查询排除停用词的问题排查
问题排查与解决
核心原因
你遇到的问题本质是查询分词逻辑导致空查询匹配所有文档,具体拆解:
- 索引阶段:文档中的
Messi会被standard分词器拆分为messi,随后被你的english_stop过滤器(因stop.txt包含messi)直接移除,因此这些文档的索引中不会存储messi这个token;而Messiis会被拆分为messiis,不在stop词列表中,会被正常保留。 - 查询阶段:使用
query_string查询messi*时,默认会使用字段配置的english_analyzer处理查询词——messi被拆分出来后直接被stop过滤器剔除,最终查询变为无实际匹配条件的空查询,自然会返回所有文档。
解决办法
提供两种可行方案:
方案1:查询时指定跳过stop过滤的分析器
直接修改查询DSL,为query_string指定analyzer: "standard",这样查询词messi*不会经过stop过滤器处理,会直接匹配以messi开头的token(即messiis):
{ "query": { "bool": { "must": { "query_string": { "query": "messi*", "fields": ["name^128"], "analyzer": "standard" } } } } }
方案2:新增专门的查询分析器(更规范)
如果希望无需每次查询都指定analyzer,可以修改索引配置,新增一个不含stop过滤的查询分析器,并为字段指定查询时使用该分析器:
- 关闭目标索引(若索引已创建),更新索引设置:
PUT /player/_settings { "index": { "analysis": { "filter": { "synonym_en": {"type": "synonym","synonyms_path": "synom.txt"}, "english_stop": {"type": "stop","stopwords_path": "stop.txt"} }, "analyzer": { "english_analyzer": { "tokenizer": "standard", "filter": ["english_stop", "synonym_en"] }, "english_search_analyzer": { "tokenizer": "standard", "filter": ["synonym_en"] } } } } }
- 更新字段映射:
PUT /player/_mapping { "properties": { "name": { "type": "text", "analyzer": "english_analyzer", "search_analyzer": "english_search_analyzer" } } }
完成配置更新后,使用原查询DSL即可仅返回包含messiis的文档。
内容的提问来源于stack exchange,提问作者sim
相关产品推荐
相关产品推荐

