Elasticsearch添加sort排序规则后查询返回错误结果如何解决?
问题根因
这是Elasticsearch bool查询的上下文规则导致的:
当bool查询被放置在must/filter上下文中时,如果该bool内部只有should子句、没有配置minimum_should_match参数,那么should的规则不会作为过滤条件生效——匹配到should条件的文档只会获得更高的相关性得分,不匹配的文档也不会被排除,只是得分为0。
你没加sort的时候,Elasticsearch默认按相关性得分_score降序排序,所有匹配ProcessId = from-cn的文档得分都高于0,不匹配的文档得分为0,所以前100条结果都是匹配的,让你误以为查询逻辑是正确的。
当你新增按CreatedTimeStamp排序的规则后,排序优先级完全覆盖了_score排序,只要文档的CreatedTimeStamp足够新,哪怕不匹配ProcessId条件、得分为0,也会排到前100条的结果中,就出现了你看到的无关结果。
修复方案
三种方案按需选择即可:
- 简化查询结构,直接把匹配条件放到外层
must中,去掉多余的嵌套bool:
{ "size": 100, "from": 0, "sort": [{"CreatedTimeStamp": {"order": "desc"}}], "query": { "bool": { "must": [{"match": {"ProcessId": "from-cn"}}] } } }
- 给嵌套的内层
bool新增minimum_should_match: 1参数,强制要求should子句至少匹配1条才会返回文档:
{ "size": 100, "from": 0, "sort": [{"CreatedTimeStamp": {"order": "desc"}}], "query": { "bool": { "must": [ { "bool": { "should": [{"match": {"ProcessId": "from-cn"}}], "minimum_should_match": 1 } } ] } } }
- 如果
ProcessId是精确匹配的关键字段,建议把match改成term,并且放到filter上下文里,还可以省去相关性得分计算,查询效率更高:
{ "size": 100, "from": 0, "sort": [{"CreatedTimeStamp": {"order": "desc"}}], "query": { "bool": { "filter": [{"term": {"ProcessId.keyword": "from-cn"}}] } } }
内容的提问来源于stack exchange,提问作者benmessi12040
相关产品推荐
相关产品推荐

