Elasticsearch 6.7.1查询返回无指定键文档的问题求助
看起来你遇到的是ES版本升级后查询行为的细微变化——6.7.x对查询字符串中缺失/Null字段的处理逻辑和6.4.2有所不同,导致原本应该被过滤掉的文档(properties.foreignKeys和properties.primaryKeyMetadata均为Null)被意外返回了。
问题根源
你的查询语句* AND ( properties.foreignKeys.referenceTableId :(file_datatypes) OR properties.primaryKeyMetadata.referenceTables :(file_datatypes) )中,*等价于match_all(匹配所有文档),而括号内的OR条件在6.7.1中,当两个字段均为Null或完全不存在时,ES并没有将这个OR条件判定为“不匹配”,反而让整个查询逻辑退化为match_all + 无有效约束,最终返回了所有文档,包括不符合预期的那些。
修复方案
你需要明确约束:必须存在其中一个目标字段,且该字段的值匹配指定内容。可以通过两种方式实现:
方式1:使用结构化Bool查询(推荐)
结构化查询比查询字符串更清晰,也能有效避免版本间的行为差异:
{ "query": { "bool": { "must": [ { "bool": { "should": [ { "term": { "properties.foreignKeys.referenceTableId": "file_datatypes" } }, { "term": { "properties.primaryKeyMetadata.referenceTables": "file_datatypes" } } ], "minimum_should_match": 1, "filter": { "bool": { "should": [ { "exists": { "field": "properties.foreignKeys.referenceTableId" } }, { "exists": { "field": "properties.primaryKeyMetadata.referenceTables" } } ], "minimum_should_match": 1 } } } } ] } } }
should数组确保至少匹配其中一个值条件filter里的exists约束确保至少有一个目标字段存在(排除Null或完全缺失的情况)minimum_should_match:1明确要求至少满足一个子条件
方式2:修改查询字符串
如果偏好使用查询字符串,可以加入_exists_条件来过滤掉无目标字段的文档:
* AND ( (properties.foreignKeys.referenceTableId:(file_datatypes) AND _exists_:properties.foreignKeys.referenceTableId) OR (properties.primaryKeyMetadata.referenceTables:(file_datatypes) AND _exists_:properties.primaryKeyMetadata.referenceTables) )
这样每个OR分支都同时检查字段存在性和值匹配,确保只有符合条件的文档被返回。
验证建议
你可以先在Dev Tools中测试修复后的查询,对比返回结果,确认那些properties.foreignKeys和properties.primaryKeyMetadata均为Null的文档已经被过滤掉。
内容的提问来源于stack exchange,提问作者Abinash

