如何用Elasticsearch Java客户端(QueryBuilder)组合多过滤查询与should子句
Elasticsearch Java 客户端实现指定查询方案
针对你给出的JSON查询,以下是使用Elasticsearch Java客户端(以8.x版本为例)的实现代码,同时标注关键注意点:
核心代码实现
先确保已引入Elasticsearch Java客户端依赖,再按以下步骤编写查询逻辑:
import co.elastic.clients.elasticsearch.ElasticsearchClient; import co.elastic.clients.elasticsearch.core.SearchRequest; import co.elastic.clients.elasticsearch.core.SearchResponse; import co.elastic.clients.elasticsearch.core.search.Query; import co.elastic.clients.elasticsearch.core.search.Hit; import co.elastic.clients.json.jackson.JacksonJsonpMapper; import co.elastic.clients.transport.ElasticsearchTransport; import co.elastic.clients.transport.rest_client.RestClientTransport; import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; import java.io.IOException; import java.util.List; public class EsQueryExample { public static void main(String[] args) throws IOException { // 1. 初始化客户端连接 RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200, "http")).build(); ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper()); ElasticsearchClient client = new ElasticsearchClient(transport); // 2. 构建Range查询:匹配age >= 57的文档 Query rangeQuery = Query.of(q -> q.range(r -> r .field("age") .gte(57L) // age为long类型,传入Long值 )); // 3. 构建Terms查询:匹配指定_id列表的文档 Query termsQuery = Query.of(q -> q.terms(t -> t .field("_id") .terms(te -> te.value(List.of("1212yas1", "sdfsfs1"))) )); // 4. 构建QueryString查询:匹配hobbies.hobby中的football或Cricket Query queryStringQuery = Query.of(q -> q.queryString(qs -> qs .query("(football) OR (Cricket)") .defaultField("hobbies.hobby") )); // 5. 组合Bool查询:将子查询分配到filter和should子句 Query boolQuery = Query.of(q -> q.bool(b -> b .filter(rangeQuery, termsQuery) .should(queryStringQuery) )); // 6. 创建查询请求并执行 SearchRequest searchRequest = SearchRequest.of(s -> s .index("your_index_name") // 替换为你的目标索引名 .query(boolQuery) ); SearchResponse<Object> response = client.search(searchRequest, Object.class); // 7. 遍历处理查询结果 for (Hit<Object> hit : response.hits().hits()) { System.out.println("文档ID: " + hit.id()); System.out.println("文档内容: " + hit.source()); } // 8. 关闭客户端资源 transport.close(); restClient.close(); } }
关键注意事项
- 嵌套字段特殊处理:如果
hobbies是nested类型,直接用上述query_string查询无法正确匹配嵌套对象内的hobby值,需要将其包裹在NestedQuery中,修改代码如下:
Query nestedQuery = Query.of(q -> q.nested(n -> n .path("hobbies") .query(queryStringQuery) )); // 替换Bool查询中的should子句 Query boolQuery = Query.of(q -> q.bool(b -> b .filter(rangeQuery, termsQuery) .should(nestedQuery) ));
- 数据类型匹配:
age为long类型,构建range查询时必须传入Long类型数值,避免类型不匹配报错。 - 版本兼容性:保证项目依赖的Java客户端版本与Elasticsearch集群版本一致,避免出现兼容性问题。
内容的提问来源于stack exchange,提问作者Pradip
相关产品推荐
相关产品推荐

