使用 Tablestore Go SDK 对多元索引查询结果计算指标或按条件分组。
前提条件
安装Tablestore Go SDK并初始化客户端。
功能说明
统计聚合在查询结果上计算平均值、最大值、最小值、总和、计数、去重计数、百分位数或 TopRows,也可以按字段、范围、日期、地理位置、过滤条件和组合键分组。用于指标聚合或按字段值、范围、直方图等方式分组的字段必须启用排序与统计聚合;GroupByFilter 中的过滤条件遵循对应查询类型的字段要求。
去重计数、百分位数和字段值分组采用近似计算。去重计数小于 1 万时结果接近精确值,达到 1 亿时误差约为 2%。百分位越接近两端通常越准确,例如 P1 或 P99 通常比 P50 更准确。字段值分组并行计算时可能存在少量误差。
多个统计聚合可以组合使用。聚合数量多或嵌套层级深时会增加请求复杂度并影响响应速度。嵌套层级限制请参见多元索引使用限制。
以下示例查询多元索引中的全部数据,计算价格的最小值、最大值、总和、平均值、非空值数量、类别去重数和 P50,并按类别分组。
searchQuery := search.NewSearchQuery().
SetQuery(&search.MatchAllQuery{}).
SetLimit(0).
Aggregation(
search.NewMinAggregation("min_price", "price"),
search.NewMaxAggregation("max_price", "price"),
search.NewSumAggregation("sum_price", "price"),
search.NewAvgAggregation("avg_price", "price"),
search.NewCountAggregation("price_count", "price"),
search.NewDistinctCountAggregation("category_count", "category"),
search.NewPercentilesAggregation("price_percentiles", "price").
SetPercents([]float64{50}),
).
GroupBy(search.NewGroupByField("category_group", "category").Size(10))
response, err := client.Search(&tablestore.SearchRequest{
TableName: "example_table",
IndexName: "example_index",
SearchQuery: searchQuery,
})
if err != nil {
log.Fatal(err)
}
minResult, err := response.AggregationResults.Min("min_price")
if err != nil {
log.Fatal(err)
}
maxResult, err := response.AggregationResults.Max("max_price")
if err != nil {
log.Fatal(err)
}
sumResult, err := response.AggregationResults.Sum("sum_price")
if err != nil {
log.Fatal(err)
}
avg, err := response.AggregationResults.Avg("avg_price")
if err != nil {
log.Fatal(err)
}
countResult, err := response.AggregationResults.Count("price_count")
if err != nil {
log.Fatal(err)
}
distinctResult, err := response.AggregationResults.DistinctCount("category_count")
if err != nil {
log.Fatal(err)
}
percentilesResult, err := response.AggregationResults.Percentiles("price_percentiles")
if err != nil {
log.Fatal(err)
}
groups, err := response.GroupByResults.GroupByField("category_group")
if err != nil {
log.Fatal(err)
}
fmt.Println(minResult.Value, maxResult.Value, sumResult.Value)
fmt.Println(avg.Value)
fmt.Println(countResult.Value, distinctResult.Value)
fmt.Println(percentilesResult.PercentilesAggregationItems)
fmt.Println(groups.Items)
参数说明
查询请求
|
名称 |
类型 |
说明 |
|
TableName(必选) |
string |
数据表名称。 |
|
IndexName(必选) |
string |
多元索引名称。 |
|
SearchQuery(必选) |
search.SearchQuery |
查询条件、指标聚合和分组配置。 |
|
ColumnsToGet(可选) |
*tablestore.ColumnsToGet |
返回列配置,仅 TopRowsAggregation 返回分组内行时生效。未设置时只返回主键列。 |
|
RoutingValues(可选) |
[]*tablestore.PrimaryKey |
自定义路由字段对应的主键值列表。未配置自定义路由时无需设置。 |
|
TimeoutMs(可选) |
*int32 |
请求级超时时间,单位为毫秒。 |
查询配置
|
名称 |
类型 |
说明 |
|
SetQuery(必选) |
search.Query |
设置查询条件。 |
|
SetOffset(可选) |
int32 |
设置本次查询的起始位置,默认值为 0。使用 Offset 翻页时,Offset + Limit 不能超过 100000。 |
|
SetLimit(可选) |
int32 |
设置本次查询返回的最大行数,默认值为 10,最大值为 100。设置为 0 时不返回具体行。 |
|
SetCollapse(可选) |
*search.Collapse |
设置结果折叠。配置方法请参见折叠(去重)。 |
|
SetSort(可选) |
*search.Sort |
设置返回结果的排序方式。配置方法请参见排序和翻页。 |
|
SetGetTotalCount(可选) |
bool |
是否统计匹配总行数,默认值为 false。 |
|
SetToken(可选) |
[]byte |
设置上一次响应返回的 NextToken,以继续读取后续数据。调用该方法会清除 Sort,因为 Token 已包含上一页的排序条件。使用 Token 翻页时不能设置 Offset。 |
|
SetSearchFilter(可选) |
*search.SearchFilter |
对查询结果执行后过滤。配置方法请参见查询后过滤。 |
|
Aggregation(可选) |
...search.Aggregation |
设置统计聚合。配置方法请参见统计聚合。 |
|
GroupBy(可选) |
...search.GroupBy |
设置分组。配置方法请参见统计聚合。 |
指标聚合
|
名称 |
类型 |
说明 |
|
AvgAggregation(可选) |
search.AvgAggregation |
计算平均值。 |
|
MaxAggregation(可选) |
search.MaxAggregation |
计算最大值。 |
|
MinAggregation(可选) |
search.MinAggregation |
计算最小值。 |
|
SumAggregation(可选) |
search.SumAggregation |
计算总和。 |
|
CountAggregation(可选) |
search.CountAggregation |
计算非空值数量。 |
|
DistinctCountAggregation(可选) |
search.DistinctCountAggregation |
计算不同值数量。 |
|
PercentilesAggregation(可选) |
search.PercentilesAggregation |
计算百分位数。 |
|
TopRowsAggregation(可选) |
search.TopRowsAggregation |
返回分组内的前若干行。 |
MinAggregation、MaxAggregation、AvgAggregation 和 SumAggregation
|
名称 |
类型 |
说明 |
|
AggName(必选) |
string |
聚合名称,在读取结果时作为标识。 |
|
Field(必选) |
string |
聚合字段名称。Min、Max 和 Avg 支持 Long、Double 和 Date,Sum 支持 Long 和 Double。 |
|
MissingValue(可选) |
interface{} |
字段缺失时参与计算的替代值。未设置时忽略字段缺失的行。 |
CountAggregation 和 DistinctCountAggregation
|
名称 |
类型 |
说明 |
|
AggName(必选) |
string |
聚合名称。 |
|
Field(必选) |
string |
统计字段名称,支持 Long、Double、Boolean、Keyword、Date、IP 和 Geo-point。Count 不统计字段缺失的行。 |
|
MissingValue(可选) |
interface{} |
仅 DistinctCountAggregation 支持,字段缺失时使用该值参与去重统计。未设置时忽略字段缺失的行。 |
CountAggregation 统计指定字段的非空值行数,适合稀疏列。若要统计查询匹配总行数,请调用 SetGetTotalCount(true) 并读取 SearchResponse.TotalCount;若要统计多元索引全部行,查询条件使用 MatchAllQuery。
PercentilesAggregation
Go SDK 1.7.0 及以上版本支持 PercentilesAggregation。
|
名称 |
类型 |
说明 |
|
AggName(必选) |
string |
聚合名称。 |
|
Field(必选) |
string |
聚合字段名称,支持 Long、Double 和 Date。 |
|
Percents(必选) |
[]float64 |
要计算的百分位数,例如 25、50、90 和 99。 |
|
MissingValue(可选) |
interface{} |
字段缺失时参与计算的替代值。未设置时忽略字段缺失的行。 |
TopRowsAggregation
TopRowsAggregation 作为分组的子聚合使用。Go SDK 1.7.0 及以上版本支持该功能。
|
名称 |
类型 |
说明 |
|
AggName(必选) |
string |
聚合名称。 |
|
Limit(可选) |
*int32 |
每个分组内返回的最大行数,默认值为 1。 |
|
Sort(可选) |
*search.Sort |
返回行的排序方式。 |
返回哪些属性列由 SearchRequest.ColumnsToGet 控制。要直接从多元索引返回属性列,创建多元索引时必须存储相应字段;未设置返回列时只返回主键列。
分组
|
名称 |
类型 |
说明 |
|
GroupByField(可选) |
search.GroupByField |
按字段值分组。 |
|
GroupByRange(可选) |
search.GroupByRange |
按数值范围分组。 |
|
GroupByGeoDistance(可选) |
search.GroupByGeoDistance |
按地理距离分组。 |
|
GroupByFilter(可选) |
search.GroupByFilter |
按过滤条件分组。 |
|
GroupByHistogram(可选) |
search.GroupByHistogram |
按固定数值间隔分组。 |
|
GroupByDateHistogram(可选) |
search.GroupByDateHistogram |
按日期或时间间隔分组。 |
|
GroupByGeoGrid(可选) |
search.GroupByGeoGrid |
按 GeoHash 网格分组。 |
|
GroupByComposite(可选) |
search.GroupByComposite |
按多个字段的组合键分组并支持翻页。 |
GroupByField
|
名称 |
类型 |
说明 |
|
AggName(必选) |
string |
分组名称。 |
|
Field(必选) |
string |
分组字段名称,支持 Long、Double、Boolean、Keyword、Date 和 IP。 |
|
Sz(可选) |
*int32 |
返回的分组数量,默认值为 10,最大值为 2000。 |
|
Sorters(可选) |
[]search.GroupBySorter |
分组排序方式,多个规则按列表顺序生效。默认按分组内行数降序排列。 |
|
SubAggList(可选) |
[]search.Aggregation |
子聚合列表。 |
|
SubGroupByList(可选) |
[]search.GroupBy |
子分组列表。 |
分组排序
分组支持以下排序类型:
GroupKeyGroupBySort:按分组值的字典序升序或降序排列。RowCountGroupBySort:按分组内行数升序或降序排列,默认按此类型降序排列。SubAggGroupBySort:按指定子指标聚合的结果升序或降序排列。
GroupByRange
|
名称 |
类型 |
说明 |
|
AggName(必选) |
string |
分组名称。 |
|
Field(必选) |
string |
分组字段名称,支持 Long 和 Double。 |
|
RangeList(必选) |
[]search.Range |
左闭右开的分组范围列表。边界可使用 search.NegInf 和 search.Inf。 |
|
SubAggList(可选) |
[]search.Aggregation |
子聚合列表。 |
|
SubGroupByList(可选) |
[]search.GroupBy |
子分组列表。 |
GroupByGeoDistance
|
名称 |
类型 |
说明 |
|
AggName(必选) |
string |
分组名称。 |
|
Field(必选) |
string |
分组字段名称,仅支持 Geo-point。 |
|
Origin(必选) |
search.GeoPoint |
中心坐标,纬度在前、经度在后。纬度范围为 [-90,+90],经度范围为 [-180,+180]。 |
|
RangeList(必选) |
[]search.Range |
左闭右开的距离范围列表,单位为米。边界可使用 search.NegInf 和 search.Inf。 |
|
SubAggList(可选) |
[]search.Aggregation |
子聚合列表。 |
|
SubGroupByList(可选) |
[]search.GroupBy |
子分组列表。 |
GroupByFilter
|
名称 |
类型 |
说明 |
|
AggName(必选) |
string |
分组名称。 |
|
Queries(必选) |
[]search.Query |
过滤条件列表,结果顺序与查询条件顺序一致。 |
|
SubAggList(可选) |
[]search.Aggregation |
子聚合列表。 |
|
SubGroupByList(可选) |
[]search.GroupBy |
子分组列表。 |
GroupByHistogram
|
名称 |
类型 |
说明 |
|
GroupByName(必选) |
string |
分组名称。 |
|
Field(必选) |
string |
分组字段名称,支持 Long 和 Double。 |
|
Interval(必选) |
interface{} |
数值分组间隔。 |
|
FieldRange(可选) |
model.FiledRange |
参与分组的字段值范围。配置后,(Max - Min) / Interval 不能超过 2000。 |
|
Missing(可选) |
interface{} |
字段缺失时使用的分组值。未设置时忽略字段缺失的行。 |
|
MinDocCount(可选) |
*int64 |
返回分组需要包含的最少行数。 |
|
Sorters(可选) |
[]search.GroupBySorter |
分组排序方式。 |
|
SubAggList(可选) |
[]search.Aggregation |
子聚合列表。 |
|
SubGroupByList(可选) |
[]search.GroupBy |
子分组列表。 |
GroupByDateHistogram
Go SDK 1.7.10 及以上版本支持 GroupByDateHistogram。
|
名称 |
类型 |
说明 |
|
GroupByName(必选) |
string |
分组名称。 |
|
Field(必选) |
string |
分组字段名称,仅支持 Date。 |
|
Interval(必选) |
model.DateTimeValue |
日期或时间分组间隔,由数值和时间单位组成。 |
|
FieldRange(可选) |
model.FiledRange |
参与分组的字段值范围。配置后,(Max - Min) / Interval 不能超过 2000。 |
|
Missing(可选) |
interface{} |
字段缺失时使用的日期分组值。未设置时忽略字段缺失的行。 |
|
MinDocCount(可选) |
*int64 |
返回分组需要包含的最少行数。 |
|
TimeZone(可选) |
*string |
格式为 +hh:mm 或 -hh:mm,例如 +08:00。Date 字段格式未包含时区时,可设置该参数避免聚合结果产生时差。 |
|
Sorters(可选) |
[]search.GroupBySorter |
分组排序方式。 |
|
SubAggList(可选) |
[]search.Aggregation |
子聚合列表。 |
|
SubGroupByList(可选) |
[]search.GroupBy |
子分组列表。 |
GroupByGeoGrid
Go SDK 1.7.12 及以上版本支持 GroupByGeoGrid。
|
名称 |
类型 |
说明 |
|
GroupByName(必选) |
string |
分组名称。 |
|
Field(必选) |
string |
Geo-point 字段名称。 |
|
Precision(必选) |
model.GeoHashPrecision |
GeoHash 网格精度。枚举序号越大,网格越小。 |
|
Size(必选) |
int64 |
返回的网格分组数量。 |
|
SubAggList(可选) |
[]search.Aggregation |
子聚合列表。 |
|
SubGroupByList(可选) |
[]search.GroupBy |
子分组列表。 |
GroupByComposite
Go SDK 1.7.15 及以上版本支持 GroupByComposite。
|
名称 |
类型 |
说明 |
|
GroupByName(必选) |
string |
分组名称。 |
|
SourceGroupByList(必选) |
[]search.GroupBy |
多字段分组源,最多包含 32 个字段,仅支持 GroupByField、GroupByHistogram 和 GroupByDateHistogram。GroupByField 源只使用名称、字段和排序;GroupByHistogram 源只使用名称、字段、间隔和排序;GroupByDateHistogram 源还可使用 TimeZone。源只支持按分组值排序,默认降序;字段值不存在时,对应键返回 null。 |
|
Size(可选) |
*int32 |
本次返回的组合键数量,默认值为 10,最大值为 2000。不能与 SuggestedSize 同时设置。 |
|
SuggestedSize(可选) |
*int32 |
面向 Spark、Presto 等计算引擎高吞吐场景的软限制。可设置为 -1 或大于服务端限制的值,实际返回数量为 min(SuggestedSize, 服务端分组限制, 总分组数)。不能与 Size 同时设置。 |
|
NextToken(可选) |
*string |
上一页分组结果返回的翻页凭证。 |
|
SubAggList(可选) |
[]search.Aggregation |
子聚合列表。 |
|
SubGroupByList(可选) |
[]search.GroupBy |
子分组列表。GroupByComposite 本身不能作为其他分组的子分组。 |
返回值
从 SearchResponse.AggregationResults 按聚合名称读取指标结果,从 SearchResponse.GroupByResults 按分组名称读取分组结果。
指标聚合结果
|
名称 |
类型 |
说明 |
|
Avg、Max、Min、Sum |
Value float64 |
分别调用 AggregationResults.Avg、Max、Min 或 Sum 并传入聚合名称,读取返回对象的 Value。Avg、Max 和 Min 可调用 HasValue 判断结果是否包含有效值。 |
|
Count、DistinctCount |
Value int64 |
分别调用 AggregationResults.Count 或 DistinctCount 并传入聚合名称,读取返回对象的 Value。 |
|
Percentiles |
PercentilesAggregationItems []search.PercentilesAggregationItem |
调用 AggregationResults.Percentiles 并传入聚合名称。每个结果项的 Key 为百分位数,Value 为对应值。 |
|
TopRows |
Value []model.Row |
调用 AggregationResults.TopRows 并传入聚合名称,读取返回对象的 Value。 |
分组结果
|
名称 |
类型 |
说明 |
|
GroupByField |
[]search.GroupByFieldResultItem |
调用 GroupByResults.GroupByField 获取结果。每项包含 Key、RowCount、SubAggregations 和 SubGroupBys。 |
|
GroupByRange |
[]search.GroupByRangeResultItem |
调用 GroupByResults.GroupByRange 获取结果。每项包含 From、To、RowCount、SubAggregations 和 SubGroupBys。 |
|
GroupByGeoDistance |
[]search.GroupByGeoDistanceResultItem |
调用 GroupByResults.GroupByGeoDistance 获取结果。每项包含距离范围 From 和 To、RowCount、SubAggregations 和 SubGroupBys。 |
|
GroupByFilter |
[]search.GroupByFilterResultItem |
调用 GroupByResults.GroupByFilter 获取结果。结果顺序与 Queries 顺序一致,每项包含 RowCount、SubAggregations 和 SubGroupBys。 |
|
GroupByHistogram |
[]search.GroupByHistogramItem |
调用 GroupByResults.GroupByHistogram 获取结果。每项的 Key 为分组值,Value 为分组内行数,并包含 SubAggregations 和 SubGroupBys。 |
|
GroupByDateHistogram |
[]search.GroupByDateHistogramItem |
调用 GroupByResults.GroupByDateHistogram 获取结果。每项包含毫秒时间戳 Timestamp、RowCount、SubAggregations 和 SubGroupBys。 |
|
GroupByGeoGrid |
[]search.GroupByGeoGridResultItem |
调用 GroupByResults.GroupByGeoGrid 获取结果。每项包含 GeoHash Key、网格边界 GeoGrid、RowCount、SubAggregations 和 SubGroupBys。 |
|
GroupByComposite |
[]search.GroupByCompositeResultItem |
调用 GroupByResults.GroupByComposite 获取结果。SourceGroupByNames 表示键顺序;每项的 Keys 与其一一对应,并包含 RowCount、SubAggregations 和 SubGroupBys。NextToken 为下一页凭证。 |
场景示例
使用子聚合和子分组
以下示例按类别分组,在每个类别中计算最高价格,并继续按状态分组。
groupBy := search.NewGroupByField("category_group", "category").
Size(10).
SubAggregation(search.NewMaxAggregation("max_price", "price")).
SubGroupBy(search.NewGroupByField("status_group", "status").Size(10))
searchQuery := search.NewSearchQuery().
SetQuery(&search.MatchAllQuery{}).
SetLimit(0).
GroupBy(groupBy)
response, err := client.Search(&tablestore.SearchRequest{
TableName: "example_table",
IndexName: "example_index",
SearchQuery: searchQuery,
})
if err != nil {
log.Fatal(err)
}
result, err := response.GroupByResults.GroupByField("category_group")
if err != nil {
log.Fatal(err)
}
for _, item := range result.Items {
maxPrice, err := item.SubAggregations.Max("max_price")
if err != nil {
log.Fatal(err)
}
statuses, err := item.SubGroupBys.GroupByField("status_group")
if err != nil {
log.Fatal(err)
}
fmt.Println(item.Key, maxPrice.Value, statuses.Items)
}
使用多字段分组并翻页
GroupByComposite 以扁平组合键返回多字段分组结果,并通过 NextToken 连续读取后续分组。
composite := search.NewGroupByComposite("category_status_group").
SourceGroupBys(
search.NewGroupByField("category", "category"),
search.NewGroupByField("status", "status"),
).
SetSize(100)
var nextToken *string
for {
if nextToken != nil {
composite.SetNextToken(nextToken)
}
searchQuery := search.NewSearchQuery().
SetQuery(&search.MatchAllQuery{}).
SetLimit(0).
GroupBy(composite)
response, err := client.Search(&tablestore.SearchRequest{
TableName: "example_table",
IndexName: "example_index",
SearchQuery: searchQuery,
})
if err != nil {
log.Fatal(err)
}
result, err := response.GroupByResults.GroupByComposite(
"category_status_group",
)
if err != nil {
log.Fatal(err)
}
for _, item := range result.Items {
fmt.Println(item.Keys, item.RowCount)
}
nextToken = result.NextToken
if nextToken == nil || *nextToken == "" {
break
}
}
按范围、距离和过滤条件分组
以下示例在同一个查询中按价格范围、地理距离和过滤条件分别分组。
priceRanges := search.NewGroupByRange("price_ranges", "price").
Range(0, 200).
Range(200, 500)
distanceRanges := search.NewGroupByGeoDistance(
"distance_ranges",
"location",
search.GeoPoint{Lat: 30.2741, Lon: 120.1551},
).
Range(0, 100000).
Range(100000, 1500000)
categoryFilters := search.NewGroupByFilter("category_filters").
Query(&search.TermQuery{FieldName: "category", Term: "book-go"}).
Query(&search.TermQuery{FieldName: "category", Term: "game"})
searchQuery := search.NewSearchQuery().
SetQuery(&search.MatchAllQuery{}).
SetLimit(0).
GroupBy(priceRanges, distanceRanges, categoryFilters)
response, err := client.Search(&tablestore.SearchRequest{
TableName: "example_table",
IndexName: "example_index",
SearchQuery: searchQuery,
})
if err != nil {
log.Fatal(err)
}
priceResult, err := response.GroupByResults.GroupByRange("price_ranges")
if err != nil {
log.Fatal(err)
}
distanceResult, err := response.GroupByResults.GroupByGeoDistance(
"distance_ranges",
)
if err != nil {
log.Fatal(err)
}
filterResult, err := response.GroupByResults.GroupByFilter("category_filters")
if err != nil {
log.Fatal(err)
}
fmt.Println(priceResult.Items)
fmt.Println(distanceResult.Items)
fmt.Println(filterResult.Items)
生成数值和日期直方图
以下示例按固定价格间隔生成数值直方图,并按月生成日期直方图。
groupKeyAscending := []search.GroupBySorter{
&search.GroupKeyGroupBySort{Order: search.SortOrder_ASC.Enum()},
}
priceHistogram := search.NewGroupByHistogram("price_histogram", "price").
SetInterval(int64(200)).
SetFiledRange(int64(0), int64(600)).
SetMinDocCount(1).
SetGroupBySorters(groupKeyAscending)
dateHistogram := search.NewGroupByDateHistogram(
"date_histogram",
"event_time",
).
SetInterval(model.DateTimeValue{
Value: proto.Int32(1),
Unit: model.DateTimeUnit_MONTH.Enum(),
}).
SetFiledRange("2026-01-01T00:00:00", "2026-05-01T00:00:00").
SetTimeZone("+08:00").
SetMinDocCount(1).
SetGroupBySorters(groupKeyAscending)
searchQuery := search.NewSearchQuery().
SetQuery(&search.MatchAllQuery{}).
SetLimit(0).
GroupBy(priceHistogram, dateHistogram)
response, err := client.Search(&tablestore.SearchRequest{
TableName: "example_table",
IndexName: "example_index",
SearchQuery: searchQuery,
})
if err != nil {
log.Fatal(err)
}
priceResult, err := response.GroupByResults.GroupByHistogram("price_histogram")
if err != nil {
log.Fatal(err)
}
dateResult, err := response.GroupByResults.GroupByDateHistogram("date_histogram")
if err != nil {
log.Fatal(err)
}
fmt.Println(priceResult.Items)
fmt.Println(dateResult.Items)
按地理网格分组
以下示例按约 39 km × 19 km 的 GeoHash 网格统计地理位置字段。
searchQuery := search.NewSearchQuery().
SetQuery(&search.MatchAllQuery{}).
SetLimit(0).
GroupBy(
search.NewGroupByGeoGrid("geo_grid", "location").
SetPrecision(model.GHP_39KM_19KM_4).
SetSize(100),
)
response, err := client.Search(&tablestore.SearchRequest{
TableName: "example_table",
IndexName: "example_index",
SearchQuery: searchQuery,
})
if err != nil {
log.Fatal(err)
}
result, err := response.GroupByResults.GroupByGeoGrid("geo_grid")
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Items)
获取分组内的行
以下示例按类别分组,并返回每个类别中价格最高的一行。
topRows := search.NewTopRowsAggregation("top_price").
SetLimit(1).
SetSort(&search.Sort{Sorters: []search.Sorter{
&search.FieldSort{
FieldName: "price",
Order: search.SortOrder_DESC.Enum(),
},
}})
groupBy := search.NewGroupByField("category_group", "category").
Size(10).
SubAggregation(topRows)
searchQuery := search.NewSearchQuery().
SetQuery(&search.MatchAllQuery{}).
SetLimit(0).
GroupBy(groupBy)
response, err := client.Search(&tablestore.SearchRequest{
TableName: "example_table",
IndexName: "example_index",
SearchQuery: searchQuery,
ColumnsToGet: &tablestore.ColumnsToGet{
Columns: []string{"category", "price"},
},
})
if err != nil {
log.Fatal(err)
}
groups, err := response.GroupByResults.GroupByField("category_group")
if err != nil {
log.Fatal(err)
}
for _, item := range groups.Items {
rows, err := item.SubAggregations.TopRows("top_price")
if err != nil {
log.Fatal(err)
}
fmt.Println(item.Key, rows.Value)
}
多字段分组方式对比
按多个字段分组时,可以嵌套多个 GroupByField,也可以使用 GroupByComposite。根据返回结构、排序和是否需要翻页选择。
|
方式 |
特点 |
|
嵌套 GroupByField |
按父子层级返回,每层最多返回 2000 个分组;不支持分组翻页;支持按分组值、行数或子聚合值排序,并支持子聚合。 |
|
GroupByComposite |
以扁平组合键返回,最多包含 32 个字段;每页最多返回 2000 个分组并支持通过 NextToken 翻页;每个分组源仅支持按分组值排序,默认降序。Date 字段的分组键以时间戳字符串返回。 |