
本文将详细指导如何将包含多层布尔逻辑(`must` 和 `should`)以及 `multi_match` 和 `match` 子句的复杂elasticsearch嵌套查询,高效地转换为java high-level rest client api代码。通过具体的代码示例,帮助开发者理解并实现此类复杂查询的java编程。
在Elasticsearch中,复杂的查询通常通过组合不同的查询子句来实现,其中布尔查询(bool query)是核心。它允许我们使用 must(必须匹配)、should(应该匹配,影响相关性评分或作为OR条件)、filter(必须匹配,不影响评分)和 must_not(必须不匹配)等子句来构建复杂的逻辑。
我们来看一个典型的嵌套布尔查询JSON结构:
GET /list/_search
{
"size": 12,
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"multi_match": {
"query": "city hed",
"type": "bool_prefix",
"fields": [
"cityName",
"countryCodeName",
"iso"
]
}
},
{
"multi_match": {
"query": "city hed",
"fuzziness": "AUTO",
"fields": [
"cityName*"
]
}
}
]
}
},
{
"bool": {
"should": [
{
"match": {
"iso": ""
}
},
{
"match": {
"iso": ""
}
}
]
}
}
]
}
}
}这个查询的结构可以分解为:
理解这种层次结构是将其转换为Java API的关键。
立即学习“Java免费学习笔记(深入)”;
Elasticsearch Java High-Level REST Client 提供了一套流畅的API来构建和执行查询。核心组件包括 SearchRequest、SearchSourceBuilder 和 QueryBuilders。
我们首先从最内层的查询开始构建,逐步向外组合。
1. 构建 multi_match 查询
第一个 multi_match 查询使用了 bool_prefix 类型,匹配 cityName, countryCodeName, iso 字段。 第二个 multi_match 查询使用了 fuzziness: "AUTO",匹配 cityName* 字段。
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder.Type;
import org.elasticsearch.index.query.QueryBuilders;
// multi_match 查询1: 对应 JSON 中的 "type": "bool_prefix"
MultiMatchQueryBuilder multiMatchQuery1 = QueryBuilders
.multiMatchQuery("city hed", "cityName", "countryCodeName", "iso")
.type(Type.BOOL_PREFIX); // 对应 JSON 的 "bool_prefix"
// multi_match 查询2: 对应 JSON 中的 "fuzziness": "AUTO"
MultiMatchQueryBuilder multiMatchQuery2 = QueryBuilders
.multiMatchQuery("city hed", "cityName*")
.fuzziness("AUTO"); // 可以是 "AUTO" 或具体数字,例如 "2"2. 构建 match 查询
这两个 match 查询都针对 iso 字段,且查询值为一个空字符串。
import org.elasticsearch.index.query.MatchQueryBuilder;
MatchQueryBuilder matchQuery1 = QueryBuilders.matchQuery("iso", "");
MatchQueryBuilder matchQuery2 = QueryBuilders.matchQuery("iso", "");3. 组合为内部 should 布尔查询
现在,我们将上述构建的查询组合成两个内部的 should 布尔查询。
import org.elasticsearch.index.query.BoolQueryBuilder;
// 组合第一个 should 布尔查询
BoolQueryBuilder innerBoolShould1 = QueryBuilders.boolQuery()
.should(multiMatchQuery1)
.should(multiMatchQuery2);
// 组合第二个 should 布尔查询
BoolQueryBuilder innerBoolShould2 = QueryBuilders.boolQuery()
.should(matchQuery1)
.should(matchQuery2);最后,我们将这两个内部的 should 布尔查询作为 must 条件,组合到最外层的布尔查询中。
BoolQueryBuilder outerBoolMust = QueryBuilders.boolQuery()
.must(innerBoolShould1)
.must(innerBoolShould2);将所有部分整合,并加入 SearchRequest 和 SearchSourceBuilder 的初始化,以及执行搜索请求的代码。
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder.Type;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import java.io.IOException;
public class ElasticsearchComplexQueryExample {
// 假设您已经初始化了RestHighLevelClient client
// 实际应用中,RestHighLevelClient应作为单例或通过依赖注入管理
private final RestHighLevelClient client;
public ElasticsearchComplexQueryExample(RestHighLevelClient client) {
this.client = client;
}
public SearchResponse executeComplexNestedQuery() throws IOException {
SearchRequest searchRequest = new SearchRequest("list"); // 替换为您的索引名称
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.size(12); // 设置返回结果数量,对应 JSON 中的 "size": 12
// --- 构建第一个内部 should 查询 ---
// multi_match 查询1: 对应 JSON 中的 "type": "bool_prefix"
MultiMatchQueryBuilder multiMatchQuery1 = QueryBuilders
.multiMatchQuery("city hed", "cityName", "countryCodeName", "iso")
.type(Type.BOOL_PREFIX);
// multi_match 查询2: 对应 JSON 中的 "fuzziness": "AUTO"
MultiMatchQueryBuilder multiMatchQuery2 = QueryBuilders
.multiMatchQuery("city hed", "cityName*")
.fuzziness("AUTO");
// 组合第一个 should 布尔查询
BoolQueryBuilder innerBoolShould1 = QueryBuilders.boolQuery()
.should(multiMatchQuery1)
.should(multiMatchQuery2);
// --- 构建第二个内部 should 查询 ---
MatchQueryBuilder matchQuery1 = QueryBuilders.matchQuery("iso", "");
MatchQueryBuilder matchQuery2 = QueryBuilders.matchQuery("iso", "");
// 组合第二个 should 布尔查询
BoolQueryBuilder innerBoolShould2 = QueryBuilders.boolQuery()
.should(matchQuery1)
.should(matchQuery2);
// --- 构建最外层 must 查询 ---
BoolQueryBuilder outerBoolMust = QueryBuilders.boolQuery()
.must(innerBoolShould1)
.must(innerBoolShould2);
searchSourceBuilder.query(outerBoolMust); // 将构建好的查询设置到 SearchSourceBuilder
searchRequest.source(searchSourceBuilder); // 将 SearchSourceBuilder 设置到 SearchRequest
// 执行搜索请求
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
return searchResponse;
}
// 示例:如何使用此方法
public static void main(String[] args) {
// 实际使用时需要初始化 RestHighLevelClient
// 例如:
// RestHighLevelClient client = new RestHighLevelClient(
// RestClient.builder(new HttpHost("localhost", 9200, "http")));
// 为了示例运行,这里使用一个模拟的客户端或者跳过实际执行
RestHighLevelClient mockClient = null; // 替换为您的实际客户端
try {
ElasticsearchComplexQueryExample example = new ElasticsearchComplexQueryExample(mockClient);
SearchResponse response = example.executeComplexNestedQuery();
System.out.println("Search completed. Hits: " + response.getHits().getTotalHits().value);
// 处理搜索结果...
} catch (IOException e) {
System.err.println("Error during search: " + e.getMessage());
e.printStackTrace();
} finally {
// 确保客户端在不再需要时关闭
// if (mockClient != null) {
// try {
// mockClient.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
}
}
}通过Java High-Level REST Client API,开发者可以利用 QueryBuilders 提供的丰富方法,以高度灵活和可读性强的方式构建复杂的Elasticsearch查询。将嵌套的布尔逻辑分解为更小的、可管理的 BoolQueryBuilder 实例,然后逐步组合它们,是处理此类复杂查询的有效策略。遵循上述最佳实践,可以确保查询的正确性、性能和代码的可维护性。
以上就是Elasticsearch复杂布尔嵌套查询的Java API实现指南的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号