从ElasticSearch 1.7迁移至7.17:Java Client API实现filteredQuery遇问题
Elasticsearch 1.7 迁移到7.17:filteredQuery的Java Client替代实现问题
原Elasticsearch 1.7.5代码实现
在1.7.5版本中,使用filteredQuery实现查询+过滤的代码如下:
QueryBuilder queryBuilder = QueryBuilders.filteredQuery(QueryBuilders.matchAllQuery(), FilterBuilders.inFilter("_id", someList));
生成的DSL查询语句为:
{ "filtered" : { "query" : { "match_all" : { } }, "filter" : { "terms" : { "_id" : [ "1", "2", "3" ] } } } }
filteredQuery的作用是:对另一个查询的结果应用过滤器,参数分别为要过滤的查询和要应用的过滤器。
当前7.17版本的尝试代码
你目前使用7.17 Java Client的代码如下:
Query.Builder queryBuilder = (Query.Builder) new Query.Builder() .bool(bBuilder -> bBuilder .must(MatchAllQuery.of(b -> b)._toQuery()) .filter(fBuilder -> fBuilder.ids( idBuilder-> idBuilder.values(someList) ) ));
生成的DSL为:
{ "bool": { "filter": [ { "ids": { "values": [ "1", "2", "3" ] } } ], "must": [ { "match_all": { } } ] } }
问题原因与正确实现
结果不一致的核心原因是:原代码使用的是针对_id字段的terms过滤器,而你当前用的是ids查询,这两者在处理逻辑上存在差异(比如ids是专门匹配文档ID的查询类型,而terms是针对字段的过滤,在类型匹配、处理逻辑上有细微区别)。
正确的7.17 Java Client代码应该还原原逻辑,在filter中使用terms查询针对_id字段:
Query.Builder queryBuilder = new Query.Builder() .bool(b -> b .must(MatchAllQuery.of(m -> m)._toQuery()) .filter(f -> f.terms(t -> t .field("_id") .values(someList) )) );
这段代码生成的DSL为:
{ "bool": { "must": [ { "match_all": {} } ], "filter": [ { "terms": { "_id": ["1", "2", "3"] } } ] } }
这个DSL和原filteredQuery的逻辑完全等价:先执行match_all查询,再用terms过滤_id字段,确保结果和原版本一致。
另外需要注意:
- 确保
someList中的元素类型与Elasticsearch中_id字段的类型完全匹配(比如原版本中_id是字符串,7.x中也保持一致) - 在7.x版本中,
filtered查询已被官方废弃,推荐使用bool查询的must+filter组合替代,这也是上述代码的实现依据
内容的提问来源于stack exchange,提问作者devilhector
相关产品推荐
相关产品推荐

