You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Java API的QueryBuilder实现Elasticsearch嵌套分组查询

基于Elasticsearch Java API按@geo.Source.Country.IsoCode分组统计的实现方案

要实现按@geo.Source.Country.IsoCode字段分组统计并得到指定格式的结果,核心是使用Elasticsearch的Terms Aggregation(词条聚合)完成分组计数,以下是具体实现方案:

1. 完整代码实现

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.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

// 假设已初始化RestHighLevelClient实例(client)
public class GeoCountryAggregation {
    public static List<Map<String, Object>> queryCountryIsoCodeCount(String targetIndex) throws IOException {
        // 构建词条聚合:按@geo.Source.Country.IsoCode字段分组
        TermsAggregationBuilder isoCodeAgg = AggregationBuilders.terms("country_iso_agg")
                .field("@geo.Source.Country.IsoCode.keyword") // 必须用keyword类型避免分词干扰
                .size(100); // 控制返回的分组数量,按需调整

        // 构建搜索请求,只返回聚合结果
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchAllQuery()) // 替换为你的过滤条件(如时间范围、severity过滤等)
                .aggregation(isoCodeAgg)
                .size(0); // 设置为0,不返回原始文档,提升效率

        SearchRequest searchRequest = new SearchRequest(targetIndex);
        searchRequest.source(sourceBuilder);

        // 执行请求并解析结果
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        Terms termsAggResult = response.getAggregations().get("country_iso_agg");

        List<Map<String, Object>> resultList = new ArrayList<>();
        for (Terms.Bucket bucket : termsAggResult.getBuckets()) {
            resultList.add(Map.of(
                    "iso_code", bucket.getKeyAsString(),
                    "count", bucket.getDocCount()
            ));
        }

        return resultList;
    }
}

2. 关键注意事项

  • 字段后缀.keyword:如果@geo.Source.Country.IsoCode字段类型是text,必须使用.keyword后缀引用其不分词的子字段,否则分词会导致分组结果混乱(比如"US"被拆分成单个字符)。
  • 聚合名称唯一性:country_iso_agg是自定义的聚合标识,需确保在同一个搜索请求中唯一,用于后续从响应中提取聚合数据。
  • 结果数量控制:terms.size(100)限制返回的分组数,若需要更多分组可增大该值;sourceBuilder.size(0)避免返回原始文档,大幅提升查询性能。
  • 过滤条件扩展:将QueryBuilders.matchAllQuery()替换为实际业务需要的过滤查询(如QueryBuilders.rangeQuery("timestamp").gte("2022-11-01")),实现特定范围内的统计。

3. 返回结果示例

执行代码后,返回的List结构完全符合需求:

[{"iso_code": "US", "count": 15}, {"iso_code": "AE", "count": 102}, {"iso_code": "UA", "count": 8}]

内容的提问来源于stack exchange,提问作者Hayk Mkhitaryan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 23:30:50