Elasticsearch中must_not查询对空字段未返回预期结果问题求助
问题根源
- 逻辑不匹配需求:现有查询的
must_not规则是排除noteType = SYSTEM_GENERATED的文档,和你要排除的「noteType不存在、noteType为null」的目标没有关联,逻辑完全偏离。 - 缺少字段存在性校验:ES中判断字段是否存在、是否为null不能用普通term查询,需要使用专用的
exists查询实现。
调整方案
1. DSL修改
在bool查询的must数组中新增exists查询,用来过滤掉noteType不存在或为null的文档,示例如下:
{ "query": { "bool": { "must": [ { "term": { "projectId": { "value": "95", "boost": 1.0 } } }, { "range": { "createTimeInMs": { "from": null, "to": 1633594455000, "include_lower": true, "include_upper": true, "boost": 1.0 } } }, // 新增:要求noteType字段存在且值非null { "exists": { "field": "noteType" } } ], // 如果你还有排除SYSTEM_GENERATED类型的业务需求,保留下面的must_not,否则直接删除即可 "must_not": [ { "term": { "noteType": { "value": "SYSTEM_GENERATED", "boost": 1.0 } } } ], "adjust_pure_negative": true, "boost": 1.0 } } }
2. Java代码修改
对应的Java代码只要新增一行exists查询的配置即可:
BoolQueryBuilder queryBuilder= QueryBuilders.boolQuery(); queryBuilder.must(QueryBuilders.termQuery("projectId", requestInfo.getProjectId())); queryBuilder.must(rangeQuery("createTimeInMs").lte(requestInfo.getCreateTimeInMs())); // 新增:过滤noteType不存在或为null的文档 queryBuilder.must(QueryBuilders.existsQuery("noteType")); if(!requestInfo.isIncludeLog()) { // 原有业务逻辑:不需要包含日志时排除系统生成的笔记 queryBuilder.mustNot(QueryBuilders.termQuery("noteType", Defs.SYSTEM_NOTE_TYPE)); }
补充说明
exists查询的生效逻辑是:仅匹配字段在文档中存在,且值不是null的文档,刚好覆盖你要排除的两种场景,不需要额外写null判断逻辑。
内容的提问来源于stack exchange,提问作者user404
相关产品推荐
相关产品推荐

