统计聚合

更新时间:
复制 MD 格式

使用 Tablestore Java SDK 可对多元索引查询结果计算指标或进行分组,支持直方图、多层分组和获取分组内的行。

前提条件

安装Tablestore Java SDK并初始化客户端。

功能说明

统计聚合在多元索引完成查询后,对所有匹配行计算指标或进行分组。使用指标聚合可计算最小值、最大值、和、平均值、行数、去重行数和百分位数;使用分组可按字段值、多个字段、数值范围、地理距离、过滤条件、数值间隔、日期间隔或地理网格统计行数。分组内还可以继续添加子指标聚合或子分组。

类别

配置类型

功能

指标聚合

MinAggregation

返回字段的最小值,类似于 SQL 的 MIN

指标聚合

MaxAggregation

返回字段的最大值,类似于 SQL 的 MAX

指标聚合

SumAggregation

返回数值字段的和,类似于 SQL 的 SUM

指标聚合

AvgAggregation

返回字段的平均值,类似于 SQL 的 AVG

指标聚合

CountAggregation

返回指定字段存在值的行数,类似于 SQL 的 COUNT(field)

指标聚合

DistinctCountAggregation

返回指定字段不同值的数量,类似于 SQL 的 COUNT(DISTINCT field)

指标聚合

PercentilesAggregation

返回指定字段的一个或多个百分位数。

指标聚合

TopRowsAggregation

在每个分组内按指定顺序返回前若干行。

分组

GroupByField

按单个字段值分组。

分组

GroupByComposite

按多个字段分组,并通过翻页凭证读取后续分组。

分组

GroupByRange

按数值范围分组。

分组

GroupByGeoDistance

按数据点与中心点之间的距离范围分组。

分组

GroupByFilter

按多个过滤条件分组。

分组

GroupByHistogram

按固定数值间隔生成直方图。

分组

GroupByDateHistogram

按固定日期或时间间隔生成直方图。

分组

GroupByGeoGrid

按 GeoHash 网格分组。

重要
  • 用于统计聚合的多元索引字段必须启用排序与统计聚合。不同聚合类型支持的字段类型不同,具体要求参见对应参数表。多元索引字段类型及其与数据表字段类型的映射关系请参见数据类型

  • 统计聚合基于查询匹配结果计算。包含统计聚合的请求比仅查询数据的请求复杂;如果不需要返回具体行,可将 limit 设置为 0

  • 去重行数、百分位数和字段值分组采用近似计算。去重行数小于 1 万时结果接近精确值,达到 1 亿时误差约为 2%。百分位越接近两端通常越准确,例如 P1 或 P99 通常比 P50 更准确。字段值分组并行计算时可能存在少量误差。

  • 多个统计聚合可以组合使用。聚合数量多或嵌套层级深时会增加请求复杂度并影响响应速度。嵌套层级限制请参见多元索引使用限制

调用 search 方法查询数据,通过 SearchQuery.aggregationList 配置指标聚合,通过 SearchQuery.groupByList 配置分组。

SearchResponse search(SearchRequest request)

以下示例查询多元索引中的全部数据,计算价格的最小值、最大值、和、平均值、行数、去重类别数和 P50,并按类别分组。

SearchQuery searchQuery = SearchQuery.newBuilder()
        .query(QueryBuilders.matchAll())
        .limit(0)
        .addAggregation(AggregationBuilders.min("min_price", "price"))
        .addAggregation(AggregationBuilders.max("max_price", "price"))
        .addAggregation(AggregationBuilders.sum("sum_price", "price"))
        .addAggregation(AggregationBuilders.avg("avg_price", "price"))
        .addAggregation(AggregationBuilders.count("price_count", "price"))
        .addAggregation(AggregationBuilders.distinctCount(
                "category_count", "category"))
        .addAggregation(AggregationBuilders.percentiles(
                "price_percentiles", "price")
                .percentiles(Arrays.asList(50.0)))
        .addGroupBy(GroupByBuilders.groupByField(
                "category_group", "category").size(10))
        .build();

SearchRequest request =
        new SearchRequest("example_table", "example_index", searchQuery);
SearchResponse response = client.search(request);

AggregationResults aggregationResults = response.getAggregationResults();
System.out.println(aggregationResults
        .getAsMinAggregationResult("min_price").getValue());
System.out.println(aggregationResults
        .getAsMaxAggregationResult("max_price").getValue());
System.out.println(aggregationResults
        .getAsSumAggregationResult("sum_price").getValue());
System.out.println(aggregationResults
        .getAsAvgAggregationResult("avg_price").getValue());
System.out.println(aggregationResults
        .getAsCountAggregationResult("price_count").getValue());
System.out.println(aggregationResults
        .getAsDistinctCountAggregationResult("category_count").getValue());
System.out.println(aggregationResults
        .getAsPercentilesAggregationResult("price_percentiles")
        .getPercentilesAggregationItems());

GroupByFieldResult groupResult = response.getGroupByResults()
        .getAsGroupByFieldResult("category_group");
for (GroupByFieldResultItem item :
        groupResult.getGroupByFieldResultItems()) {
    System.out.println(item.getKey() + ": " + item.getRowCount());
}

参数说明

查询请求

request 的类型为 SearchRequest,包含以下参数。

名称

类型

说明

tableName(必选)

String

数据表名称。

indexName(必选)

String

多元索引名称。

searchQuery(必选)

SearchQuery

查询条件和统计聚合配置。

columnsToGet(可选)

SearchRequest.ColumnsToGet

返回列配置。仅 TopRowsAggregation 返回分组内行时生效;未设置时只返回主键列。

timeoutInMillisecond(可选)

int

请求级查询超时时间,单位为毫秒。默认值为 -1,表示不单独设置查询超时时间。

routingValues(可选)

List<PrimaryKey>

自定义路由字段对应的主键值列表。未配置自定义路由时无需设置。

查询配置

request.searchQuery 的类型为 SearchQuery,包含以下与统计聚合相关的参数。

名称

类型

说明

query(必选)

Query

统计范围对应的查询条件。对多元索引中的全部数据统计时,设置为 MatchAllQuery

aggregationList(可选)

List<Aggregation>

指标聚合配置。与 groupByList 至少设置一个。

groupByList(可选)

List<GroupBy>

分组配置。与 aggregationList 至少设置一个。

limit(可选)

Integer

本次查询返回的最大行数,默认值为 10。只需要统计聚合结果时设置为 0

offset(可选)

Integer

本次查询的起始行位置,默认值为 0

sort(可选)

Sort

查询结果的排序方式,不影响指标聚合和普通分组的计算范围。

trackTotalCount(可选)

int

期望统计的最大匹配行数。设置为 TRACK_TOTAL_COUNT 时,可通过 SearchResponse.totalCount 获取查询匹配总行数。

filter(可选)

SearchFilter

query 的查询结果进行过滤,统计聚合基于过滤后的结果计算。

指标聚合

以下参数对象添加到 request.searchQuery.aggregationList[]aggName 用于从返回结果中获取对应聚合结果,同一请求中的名称必须唯一。

MinAggregation、MaxAggregation 和 AvgAggregation

名称

类型

说明

aggName(必选)

String

聚合名称。

fieldName(必选)

String

聚合字段名称,支持 Long、Double 和 Date 类型。

missing(可选)

ColumnValue

缺少 fieldName 字段时使用的值。未设置时忽略缺少该字段的行。

SumAggregation

名称

类型

说明

aggName(必选)

String

聚合名称。

fieldName(必选)

String

聚合字段名称,支持 Long 和 Double 类型。

missing(可选)

ColumnValue

缺少 fieldName 字段时用于求和的值。未设置时忽略缺少该字段的行。

CountAggregation

名称

类型

说明

aggName(必选)

String

聚合名称。

fieldName(必选)

String

要统计非空值行数的字段名称,支持 Long、Double、Boolean、Keyword、Date、IP 和 Geo_point 类型。稀疏列中缺少该字段的行不计入结果。

如果要统计查询匹配总行数,在 SearchQuery 中设置 trackTotalCount,并读取 SearchResponse.totalCount。如果要统计多元索引中的全部行,将查询类型设置为 MatchAllQuery

DistinctCountAggregation

名称

类型

说明

aggName(必选)

String

聚合名称。

fieldName(必选)

String

要去重统计的字段名称,支持 Long、Double、Boolean、Keyword、Date、IP 和 Geo_point 类型。

missing(可选)

ColumnValue

缺少 fieldName 字段时参与去重统计的值。未设置时忽略缺少该字段的行。

PercentilesAggregation

名称

类型

说明

aggName(必选)

String

聚合名称。

fieldName(必选)

String

聚合字段名称,支持 Long、Double 和 Date 类型。

percentiles(必选)

List<Double>

要计算的百分位数列表,例如 25.050.090.099.0

missing(可选)

ColumnValue

缺少 fieldName 字段时参与百分位计算的值。未设置时忽略缺少该字段的行。

TopRowsAggregation

TopRowsAggregation 作为分组的子聚合使用。

名称

类型

说明

aggName(必选)

String

聚合名称。

limit(可选)

Integer

每个分组内最多返回的行数,默认值为 1

sort(可选)

Sort

分组内行的排序方式。

返回哪些属性列由 request.columnsToGet 控制。要直接从多元索引返回属性列,请在创建多元索引时存储相应字段;未指定返回列时只返回主键。

分组

以下参数对象添加到 request.searchQuery.groupByList[]groupByName 用于从返回结果中获取对应分组结果,同一请求中的名称必须唯一。

GroupByField

名称

类型

说明

groupByName(必选)

String

分组名称。

fieldName(必选)

String

分组字段名称,支持 Long、Double、Boolean、Keyword、Date 和 IP 类型。

size(可选)

Integer

返回的分组数,默认值为 10,最大值为 2000

minDocCount(可选)

Long

分组内最少行数。行数小于该值的分组不返回。

groupBySorters(可选)

List<GroupBySorter>

分组排序规则。默认按行数降序排列。多个规则按添加顺序生效。

subAggregations(可选)

List<Aggregation>

子指标聚合,对每个分组内的数据计算指标。

subGroupBys(可选)

List<GroupBy>

子分组,对每个父分组内的数据继续分组。

groupBySorters[] 支持以下取值。

取值

说明

groupKeySortInAsc

按分组值的字典序升序排列。

groupKeySortInDesc

按分组值的字典序降序排列。

rowCountSortInAsc

按分组行数升序排列。

rowCountSortInDesc

按分组行数降序排列,默认规则。

subAggSortInAsc

按指定子指标聚合的值升序排列。

subAggSortInDesc

按指定子指标聚合的值降序排列。

GroupByComposite

名称

类型

说明

groupByName(必选)

String

分组名称。

sources(必选)

List<GroupBy>

多字段分组源,最多包含 32 个字段。支持 GroupByFieldGroupByHistogramGroupByDateHistogram。其中字段值分组可配置名称、字段和排序,数值直方图可配置名称、字段、间隔和排序,日期直方图还可配置时区。源只支持按分组值的字典序排序,默认降序;字段值不存在时,对应键返回 null

nextToken(可选)

String

下一页分组凭证。首次请求不设置;返回结果中的 nextToken 不为空时,将其原值用于下一次请求。

size(可选)

Integer

返回的分组数,默认值为 10,最大值为 2000。一般使用该参数限制返回数量。

suggestedSize(可选)

Integer

面向 Spark、Presto 等计算引擎高吞吐场景的软限制。可设置为 -1 或大于服务端限制的值,实际返回数量为 min(suggestedSize, 服务端分组限制, 总分组数)。不能与 size 同时设置。

subAggregations(可选)

List<Aggregation>

子指标聚合。

subGroupBys(可选)

List<GroupBy>

子分组。GroupByComposite 本身不能作为其他分组的子分组。

说明

nextToken 在 Java SDK 中以字符串表示。持久化或跨系统传输时,不要改变字符串内容。

GroupByRange

名称

类型

说明

groupByName(必选)

String

分组名称。

fieldName(必选)

String

分组字段名称,支持 Long 和 Double 类型。

ranges(必选)

List<Range>

分组范围列表。每个范围为左闭右开区间 [from, to);边界可使用 Double.MIN_VALUEDouble.MAX_VALUE

subAggregations(可选)

List<Aggregation>

子指标聚合。

subGroupBys(可选)

List<GroupBy>

子分组。

GroupByGeoDistance

名称

类型

说明

groupByName(必选)

String

分组名称。

fieldName(必选)

String

分组字段名称,仅支持 Geo_point 类型。

origin(必选)

GeoPoint

中心点坐标,构造参数依次为纬度和经度。纬度范围为 [-90,+90],经度范围为 [-180,+180]

ranges(必选)

List<Range>

距离范围列表,单位为米。每个范围为左闭右开区间 [from, to)

subAggregations(可选)

List<Aggregation>

子指标聚合。

subGroupBys(可选)

List<GroupBy>

子分组。

GroupByFilter

名称

类型

说明

groupByName(必选)

String

分组名称。

filters(必选)

List<Query>

过滤条件列表。结果顺序与过滤条件添加顺序一致。

subAggregations(可选)

List<Aggregation>

子指标聚合。

subGroupBys(可选)

List<GroupBy>

子分组。

GroupByHistogram

名称

类型

说明

groupByName(必选)

String

分组名称。

fieldName(必选)

String

分组字段名称,支持 Long 和 Double 类型。

interval(必选)

ColumnValue

直方图间隔。

fieldRange(可选)

FieldRange

统计范围,包含 minmax(max-min)/interval 不能超过 2000

offset(可选)

ColumnValue

桶边界相对默认起点的偏移量。

minDocCount(可选)

Long

分组内最少行数。行数小于该值的桶不返回。

missing(可选)

ColumnValue

缺少 fieldName 字段时参与直方图统计的值。未设置时忽略缺少该字段的行。

groupBySorters(可选)

List<GroupBySorter>

桶排序规则。

subAggregations(可选)

List<Aggregation>

子指标聚合。

subGroupBys(可选)

List<GroupBy>

子分组。

GroupByDateHistogram

重要

Java SDK 5.16.1 及以上版本支持日期直方图统计。Java SDK 5.13.9 及以上版本支持多元索引 Date 类型。版本信息请参见Java SDK 历史迭代版本

名称

类型

说明

groupByName(必选)

String

分组名称。

fieldName(必选)

String

分组字段名称,仅支持 Date 类型。

interval(必选)

DateTimeValue

日期或时间间隔,由数值和 DateTimeUnit 组成。

fieldRange(可选)

FieldRange

统计范围,包含 minmax(max-min)/interval 不能超过 2000

minDocCount(可选)

Long

分组内最少行数。行数小于该值的桶不返回。

missing(可选)

ColumnValue

缺少 fieldName 字段时参与直方图统计的日期值。未设置时忽略缺少该字段的行。

timeZone(可选)

String

时区,格式为 +hh:mm-hh:mm,例如 +08:00。Date 字段格式未包含时区时,可设置该参数避免聚合结果产生时差。

groupBySorters(可选)

List<GroupBySorter>

桶排序规则。

subAggregations(可选)

List<Aggregation>

子指标聚合。

subGroupBys(可选)

List<GroupBy>

子分组。

GroupByGeoGrid

名称

类型

说明

groupByName(必选)

String

分组名称。

fieldName(必选)

String

分组字段名称,仅支持 Geo_point 类型。

precision(必选)

GeoHashPrecision

GeoHash 网格精度,从约 5009 km × 4992 km 的 GHP_5009KM_4992KM_1 到约 37 mm × 19 mm 的 GHP_37MM_19MM_12,枚举值序号越大,网格越小。

size(可选)

Integer

返回的网格分组数。

subAggregations(可选)

List<Aggregation>

子指标聚合。

subGroupBys(可选)

List<GroupBy>

子分组。

返回值

search 方法返回 SearchResponse,与统计聚合相关的核心字段如下。

名称

类型

说明

aggregationResults

AggregationResults

指标聚合结果,通过 getAggregationResults() 获取。使用聚合名称获取具体类型的结果。

groupByResults

GroupByResults

分组结果,通过 getGroupByResults() 获取。使用分组名称获取具体类型的结果。

totalCount

long

查询匹配行数,通过 getTotalCount() 获取。返回值取决于 trackTotalCount 配置。

isAllSuccess

boolean

是否已成功查询全部索引分区,通过 isAllSuccess() 获取。值为 false 时,聚合结果可能不完整。

指标聚合结果

配置类型

结果类型

结果字段和获取方法

MinAggregation

MinAggregationResult

valuedouble,通过 getAsMinAggregationResult(aggName).getValue() 获取。

MaxAggregation

MaxAggregationResult

valuedouble,通过 getAsMaxAggregationResult(aggName).getValue() 获取。

SumAggregation

SumAggregationResult

valuedouble,通过 getAsSumAggregationResult(aggName).getValue() 获取。

AvgAggregation

AvgAggregationResult

valuedouble,通过 getAsAvgAggregationResult(aggName).getValue() 获取。

CountAggregation

CountAggregationResult

valuelong,通过 getAsCountAggregationResult(aggName).getValue() 获取。

DistinctCountAggregation

DistinctCountAggregationResult

valuelong,通过 getAsDistinctCountAggregationResult(aggName).getValue() 获取。

PercentilesAggregation

PercentilesAggregationResult

percentilesAggregationItemsList<PercentilesAggregationItem>,通过 getAsPercentilesAggregationResult(aggName).getPercentilesAggregationItems() 获取。每项包含 keyvalue

TopRowsAggregation

TopRowsAggregationResult

rowsList<Row>,通过 getAsTopRowsAggregationResult(aggName).getRows() 获取。

分组结果

配置类型

结果类型

核心结果字段

GroupByField

GroupByFieldResult

groupByFieldResultItems。每项包含 keyrowCountsubAggregationResultssubGroupByResults

GroupByComposite

GroupByCompositeResult

sourceNamesgroupByCompositeResultItemsnextToken。每项的 keyssourceNames 按位置对应。

GroupByRange

GroupByRangeResult

groupByRangeResultItems。每项包含 fromtorowCount

GroupByGeoDistance

GroupByGeoDistanceResult

groupByGeoDistanceResultItems。每项包含距离 fromtorowCount

GroupByFilter

GroupByFilterResult

groupByFilterResultItems。每项包含 rowCount,顺序与过滤条件一致。

GroupByHistogram

GroupByHistogramResult

groupByHistogramItems。每项包含桶起始值 key 和行数 value

GroupByDateHistogram

GroupByDateHistogramResult

groupByDateHistogramItems。每项包含毫秒时间戳 timestamprowCount

GroupByGeoGrid

GroupByGeoGridResult

groupByGeoGridResultItems。每项包含 GeoHash key、网格左上和右下坐标 geoGrid 以及 rowCount

场景示例

使用子聚合和子分组

以下示例按类别分组,在每个类别中计算最高价格,并继续按城市分组。分组排序规则按添加顺序生效。

SearchQuery searchQuery = SearchQuery.newBuilder()
        .query(QueryBuilders.matchAll())
        .limit(0)
        .addGroupBy(GroupByBuilders.groupByField(
                "category_group", "category")
                .size(10)
                .addGroupBySorter(GroupBySorter.groupKeySortInAsc())
                .addSubAggregation(AggregationBuilders.max(
                        "max_price", "price"))
                .addSubGroupBy(GroupByBuilders.groupByField(
                        "city_group", "city").size(10)))
        .build();

SearchRequest request =
        new SearchRequest("example_table", "example_index", searchQuery);
SearchResponse response = client.search(request);

GroupByFieldResult result = response.getGroupByResults()
        .getAsGroupByFieldResult("category_group");
for (GroupByFieldResultItem item :
        result.getGroupByFieldResultItems()) {
    double maxPrice = item.getSubAggregationResults()
            .getAsMaxAggregationResult("max_price")
            .getValue();
    GroupByFieldResult cityResult = item.getSubGroupByResults()
            .getAsGroupByFieldResult("city_group");
    System.out.println(item.getKey() + ": " + maxPrice);
    System.out.println(cityResult.getGroupByFieldResultItems());
}

使用多字段分组并翻页

GroupByComposite 将多列键以扁平结构返回,并支持通过 nextToken 翻页。

GroupByComposite.Builder compositeBuilder = GroupByBuilders
        .groupByComposite("category_city_group")
        .addSources(GroupByBuilders.groupByField(
                "category", "category")
                .addGroupBySorter(GroupBySorter.groupKeySortInAsc()))
        .addSources(GroupByBuilders.groupByField(
                "city", "city")
                .addGroupBySorter(GroupBySorter.groupKeySortInAsc()))
        .size(100);

String nextToken = null;
do {
    GroupByComposite groupBy = nextToken == null
            ? compositeBuilder.build()
            : compositeBuilder.nextToken(nextToken).build();
    SearchQuery searchQuery = SearchQuery.newBuilder()
            .query(QueryBuilders.matchAll())
            .limit(0)
            .addGroupBy(groupBy)
            .build();
    SearchRequest request = new SearchRequest(
            "example_table", "example_index", searchQuery);
    SearchResponse response = client.search(request);

    GroupByCompositeResult result = response.getGroupByResults()
            .getAsGroupByCompositeResult("category_city_group");
    for (GroupByCompositeResultItem item :
            result.getGroupByCompositeResultItems()) {
        System.out.println(item.getKeys() + ": " + item.getRowCount());
    }
    nextToken = result.getNextToken();
} while (nextToken != null);

按范围、距离和过滤条件分组

以下代码展示三种分组的核心配置。它们可以在同一个 SearchQuery 中组合。

GroupByRange priceRanges = GroupByBuilders
        .groupByRange("price_ranges", "price")
        .addRange(0, 100)
        .addRange(100, 500)
        .build();

GroupByGeoDistance distanceRanges = GroupByBuilders
        .groupByGeoDistance("distance_ranges", "location")
        .origin(30.2741, 120.1551)
        .addRange(0, 10000)
        .addRange(10000, 100000)
        .build();

GroupByFilter categoryFilters = GroupByBuilders
        .groupByFilter("category_filters")
        .addFilter(QueryBuilders.term("category", "books"))
        .addFilter(QueryBuilders.term("category", "games"))
        .build();

生成数值和日期直方图

以下示例分别按 20 的数值间隔和 1 个月的日期间隔分组。

GroupByHistogram priceHistogram = GroupByBuilders
        .groupByHistogram("price_histogram", "price")
        .interval(20)
        .offset(0)
        .minDocCount(1L)
        .addFieldRange(0, 100)
        .addGroupBySorter(GroupBySorter.groupKeySortInAsc())
        .build();

GroupByDateHistogram dateHistogram = GroupByBuilders
        .groupByDateHistogram("date_histogram", "event_date")
        .interval(1, DateTimeUnit.MONTH)
        .fieldRange("2026-01-01", "2026-06-01")
        .timeZone("+08:00")
        .minDocCount(1L)
        .addGroupBySorter(GroupBySorter.groupKeySortInAsc())
        .build();

SearchQuery searchQuery = SearchQuery.newBuilder()
        .query(QueryBuilders.matchAll())
        .limit(0)
        .addGroupBy(priceHistogram)
        .addGroupBy(dateHistogram)
        .build();
SearchResponse response = client.search(new SearchRequest(
        "example_table", "example_index", searchQuery));

按地理网格分组

以下示例按约 39 km × 19 km 的 GeoHash 网格统计地理位置字段。

SearchQuery searchQuery = SearchQuery.newBuilder()
        .query(QueryBuilders.matchAll())
        .limit(0)
        .addGroupBy(GroupByBuilders.groupByGeoGrid(
                "geo_grid", "location")
                .precision(GeoHashPrecision.GHP_39KM_19KM_4)
                .size(100))
        .build();

SearchResponse response = client.search(new SearchRequest(
        "example_table", "example_index", searchQuery));
GroupByGeoGridResult result = response.getGroupByResults()
        .getAsGroupByGeoGridResult("geo_grid");
System.out.println(result.getGroupByGeoGridResultItems());

获取分组内的行

以下示例按类别分组,并返回每个类别中价格最高的一行。

SearchQuery searchQuery = SearchQuery.newBuilder()
        .query(QueryBuilders.matchAll())
        .limit(0)
        .addGroupBy(GroupByBuilders.groupByField(
                "category_group", "category")
                .size(10)
                .addSubAggregation(AggregationBuilders.topRows(
                        "top_price")
                        .limit(1)
                        .sort(new Sort(Arrays.asList(
                                new FieldSort(
                                        "price", SortOrder.DESC))))))
        .build();

SearchRequest.ColumnsToGet columnsToGet =
        new SearchRequest.ColumnsToGet();
columnsToGet.setColumns(Arrays.asList("category", "price"));

SearchRequest request =
        new SearchRequest("example_table", "example_index", searchQuery);
request.setColumnsToGet(columnsToGet);
SearchResponse response = client.search(request);

GroupByFieldResult result = response.getGroupByResults()
        .getAsGroupByFieldResult("category_group");
for (GroupByFieldResultItem item :
        result.getGroupByFieldResultItems()) {
    List<Row> rows = item.getSubAggregationResults()
            .getAsTopRowsAggregationResult("top_price")
            .getRows();
    System.out.println(item.getKey() + ": " + rows);
}

多字段分组方式对比

按多个字段分组时,可嵌套多个 GroupByField,也可直接使用 GroupByComposite。根据是否需要分组翻页、返回结构和排序规则选择。

对比项

字段分组嵌套

多字段分组

配置方式

在父 GroupByField 中添加 subGroupBys

GroupByComposite.sources 中添加多个分组源。

分组数量

每层最多返回 2000 个分组。

每页最多返回 2000 个分组。

字段数量

最多嵌套 3 层。

最多 32 个字段。

返回结构

按父子层级嵌套返回。

多列键以扁平列表返回。

翻页

不支持。

支持通过 nextToken 翻页。

排序

支持按分组值、行数或子聚合值排序。

每个分组源仅支持按分组值字典序排序,默认降序。

子聚合

支持。

支持。

Date 字段兼容性

按字段定义的日期格式返回分组键。

日期分组键以时间戳字符串返回。