OpenSearch DSL如何查询两个字段值互不相等的索引记录
OpenSearch DSL查询两字段值不相等记录的实现方法
完全支持实现与SQL语句SELECT * FROM <index> WHERE FIELD1!=FIELD2;等价的查询逻辑,核心通过脚本查询完成同文档内的字段值对比。
通用DSL写法(兼容OpenSearch 1.x/2.x所有正式版本)
使用Painless脚本做字段对比,同时兼容字段缺失、空值的边界场景,避免查询报错:
GET <替换为你的索引名>/_search { "query": { "bool": { "filter": [ { "script": { "script": { "lang": "painless", "source": "doc.containsKey('FIELD1') && doc.containsKey('FIELD2') && doc['FIELD1'].size() > 0 && doc['FIELD2'].size() > 0 && doc['FIELD1'].value != doc['FIELD2'].value" } } } ] } } }
脚本的匹配逻辑:
- 校验当前文档同时存在FIELD1、FIELD2两个字段,避免字段缺失触发脚本执行异常
- 校验两个字段都存了非空有效值,排除空值匹配误差
- 对比两个字段的取值,值不相等的文档会被命中返回
特殊场景适配
- 如果对比的是
text类型字段:不要用doc['字段名'].value取值,text类型存储的是分词后的词项,直接对比结果不准,需要改用_source读取原始值,脚本片段替换为:
"source": "params._source.FIELD1 != params._source.FIELD2"
提示:读取_source的查询性能低于读取doc_values的方式,非text类型字段优先用doc取值的写法
- 如果业务逻辑里「某一个字段不存在也算不相等」,直接删掉脚本里的字段存在性、非空校验逻辑即可
- 生产环境高频使用该查询时,建议提前预编译脚本并存储,降低查询时的性能损耗
内容的提问来源于stack exchange,提问作者michele
相关产品推荐
相关产品推荐

