Elasticsearch 8.3动态添加查询对象替代if/else实现嵌套查询
Elasticsearch 8.3 动态构建Bool查询替代冗余if/else
我们想实现类似示例的嵌套查询,希望能根据生成的查询对象数量动态添加条件——比如仅按名称、仅按最高价格,或者同时按两者查询,想找个比一堆if/else更简便的方式来把查询对象加入搜索函数,使用的是Elasticsearch 8.3版本。
原示例代码
if ( name != null ){ Query byName = MatchQuery.of(m -> m .field("name") .query(searchText) )._toQuery(); } if( price != null ) { Query byMaxPrice = RangeQuery.of(r -> r .field("price") .gte(JsonData.of(maxPrice)) )._toQuery(); } if ( name != null && price != null) { SearchResponse<Product> response = esClient.search(s -> s .index("products") .query(q -> q .bool(b -> b .must(byName) .must(byMaxPrice) ) ), Product.class ); } else if ( name != null && price == null ) { SearchResponse<Product> response = esClient.search(s -> s .index("products") .query(q -> q .bool(b -> b .must(byName) ) ), Product.class ); } else if ( name == null && price != null ) { SearchResponse<Product> response = esClient.search(s -> s .index("products") .query(q -> q .bool(b -> b .must(byMaxPrice) ) ), Product.class ); }
优化方案:动态收集查询条件
可以通过收集有效的查询条件到列表,再批量注入Bool查询的must子句,彻底消除冗余的if/else分支:
// 1. 初始化列表存放有效查询条件 List<Query> mustQueries = new ArrayList<>(); // 2. 按需添加查询条件 if (name != null) { Query byName = MatchQuery.of(m -> m .field("name") .query(searchText) )._toQuery(); mustQueries.add(byName); } if (price != null) { Query byMaxPrice = RangeQuery.of(r -> r .field("price") .gte(JsonData.of(maxPrice)) )._toQuery(); mustQueries.add(byMaxPrice); } // 3. 构建搜索请求,动态注入条件 SearchResponse<Product> response; if (mustQueries.isEmpty()) { // 如果没有任何条件,查询全部文档(可根据业务调整逻辑) response = esClient.search(s -> s .index("products") .query(q -> q.matchAll(m -> m)), Product.class ); } else { response = esClient.search(s -> s .index("products") .query(q -> q .bool(b -> b.must(mustQueries)) // 批量添加must条件 ), Product.class ); }
说明
- 用
List<Query>统一管理所有非空的查询条件,避免重复编写搜索请求代码 - Elasticsearch Java客户端的
bool().must()方法支持直接传入Iterable<Query>,可以一次性注入所有条件 - 空列表分支可根据业务需求调整:比如返回空结果,或者保留matchAll查询全部文档
内容的提问来源于stack exchange,提问作者RBz
相关产品推荐
相关产品推荐

