聚合统计用于对索引中的数据做统计计算,适合在不拉取明细数据的情况下查看数据规模、字段分布和数值汇总结果,或对指定主键对应的向量做加权求和。
当前 Aggregate 方法支持以下聚合算子:
| 聚合类型 | 支持算子 | 说明 |
|---|---|---|
| 标量计数聚合 | count | 统计命中数据量。设置 GroupBy 时按字段分桶;不设置时统计全局数量。 |
| 标量计算聚合 | sum、avg、min、max | 对 CalcValueOn 指定的数值字段计算求和、平均值、最小值或最大值,也可按 GroupBy 分桶。 |
| 向量计算聚合 | vector_weighted_sum | 对 IDs 对应的向量按 Weights 加权求和。 |
标量聚合可通过 Filter 缩小统计范围。GroupBy 对应 SQL 的 GROUP BY,Filter 对应 SQL 的 WHERE。
对应的 V1 接口为:https://www.volcengine.com/docs/84313/1399339
| 功能 | V2 SDK | V1 SDK |
|---|---|---|
| 子索引 | 性能和易用性更强的分片能力研发中,敬请期待。 | 通过 partition 参数指定。 |
通过 IndexClient 调用聚合方法:
Aggregate( ctx context.Context, request model.AggRequest, opts ...vector.RequestOption, ) (*model.AggResponse, error)
调用 client.Index 创建索引客户端时,需要指定以下定位参数:
| 参数名 | 类型 | 必选 | 说明 |
|---|---|---|---|
ResourceID | string | 与 CollectionName 二选一 | Collection 的资源 ID。 |
CollectionName | string | 与 ResourceID 二选一 | Collection 名称。 |
ProjectName | string | 否 | 项目名称。通过 Collection 名称定位时可用于限定项目。 |
IndexName | string | 是 | Index 名称。 |
model.AggRequest 包含以下字段:
| 参数名 | 类型 | 必选 | 说明 |
|---|---|---|---|
Op | string | 是 | 聚合算子。支持 count、sum、avg、min、max、vector_weighted_sum。 |
Filter | model.MapStr | 否 | 过滤条件。仅标量聚合支持;语法与检索接口一致,不设置时聚合当前索引内的全部数据。 |
GroupBy | *string | 否 | 分桶字段。仅标量聚合支持;不设置时执行全局聚合。 |
CalcValueOn | *string | 条件必选 | 标量计算字段。Op 为 sum、avg、min 或 max 时必填。 |
Order | model.ScalarOrder | 否 | 分桶结果排序方向,支持 model.ScalarOrderDesc 和 model.ScalarOrderAsc,默认降序。仅分桶标量聚合生效。 |
IDs | []interface{} | 条件必选 | 参与向量加权求和的主键列表。Op 为 vector_weighted_sum 时必填,最多 2000 个。元素类型需与 Collection 主键类型一致。 |
Weights | []float64 | 条件必选 | 与 IDs 一一对应的权重列表。Op 为 vector_weighted_sum 时必填,长度必须与 IDs 相同。 |
Field 是 GroupBy 的已废弃兼容字段,新代码应使用 GroupBy。Cond 是旧版分桶计数的兼容字段,新代码不建议使用。
过滤条件的结构和支持的算子参见检索公共参数。
Op | 必填参数 | 可选参数 | 说明 |
|---|---|---|---|
count | 无 | GroupBy、Filter、Order | 统计全局数据量或按字段分桶计数。 |
sum | CalcValueOn | GroupBy、Filter、Order | 对指定数值字段求和。 |
avg | CalcValueOn | GroupBy、Filter、Order | 对指定数值字段求平均值。 |
min | CalcValueOn | GroupBy、Filter、Order | 返回指定数值字段的最小值。 |
max | CalcValueOn | GroupBy、Filter、Order | 返回指定数值字段的最大值。 |
vector_weighted_sum | IDs、Weights | 无 | 对指定主键对应的向量做加权求和。 |
字段和索引要求:
| 参数 | 支持的字段类型 | 索引要求 |
|---|---|---|
GroupBy | string、int64、bool | 字段需要已建立枚举索引。 |
CalcValueOn | int64、float32 | 字段需要已建立范围索引。 |
使用 count 时,索引中需要至少存在一个可用于聚合的标量索引字段。使用 vector_weighted_sum 时,Collection 需要包含向量字段,或在创建 Collection 时配置 Vectorize。
方法返回 *model.AggResponse:
| 字段 | 类型 | 说明 |
|---|---|---|
RequestID | string | 请求链路 ID,可用于问题排查。 |
Code | string | 响应状态码。 |
Message | string | 响应信息。 |
API | string | 实际调用的 API 名称。 |
Result | *model.AggResult | 聚合结果。 |
model.AggResult 结构:
| 字段 | 类型 | 说明 |
|---|---|---|
Op | string | 本次执行的聚合算子。 |
GroupBy | string | 分桶字段。全局标量聚合时为 __NONE__。 |
CalcValueOn | string | 标量计算字段,仅 sum、avg、min、max 返回。 |
Agg | model.MapStr | 标量聚合结果。全局聚合使用 __TOTAL__ 作为结果键。 |
VectorWeightedSum | *model.VectorWeightedSumResult | 向量加权求和结果,仅 vector_weighted_sum 返回。 |
Agg 中的 value 类型取决于算子和计算字段:
| 算子 | 结果类型 |
|---|---|
count | 整数。 |
sum、min、max | CalcValueOn 为 int64 时返回整数,为 float32 时返回浮点数。 |
avg | 浮点数。 |
model.VectorWeightedSumResult 结构:
| 字段 | 类型 | 说明 |
|---|---|---|
Vector | []float64 | 加权求和后的向量。 |
FoundIDs | []interface{} | 实际命中并参与计算的主键列表,顺序与请求中的 IDs 一致。 |
FoundCount | int64 | 实际命中并参与计算的主键数量。 |
WeightSum | float64 | 实际参与计算的权重和,未命中主键对应的权重不计入。 |
以下示例分别执行分桶计数、分桶求和和向量加权求和。运行前请配置 VIKINGDB_AK、VIKINGDB_SK、VIKINGDB_COLLECTION 和 VIKINGDB_INDEX 环境变量,并按实际地域修改 Endpoint 和 Region。
package main import ( "context" "encoding/json" "fmt" "os" "time" "github.com/volcengine/vikingdb-go-sdk/vector" "github.com/volcengine/vikingdb-go-sdk/vector/model" ) func stringPtr(value string) *string { return &value } func printResult(name string, response *model.AggResponse, err error) { if err != nil { panic(fmt.Errorf("%s failed: %w", name, err)) } data, err := json.MarshalIndent(response.Result, "", " ") if err != nil { panic(err) } fmt.Printf("%s request_id=%s result=%s\n", name, response.RequestID, data) } func main() { client, err := vector.New( vector.AuthIAM( os.Getenv("VIKINGDB_AK"), os.Getenv("VIKINGDB_SK"), ), vector.WithEndpoint("https://api-vikingdb.vikingdb.cn-beijing.volces.com"), vector.WithRegion("cn-beijing"), vector.WithTimeout(30*time.Second), vector.WithMaxRetries(3), ) if err != nil { panic(err) } index := client.Index(model.IndexLocator{ CollectionLocator: model.CollectionLocator{ CollectionName: os.Getenv("VIKINGDB_COLLECTION"), }, IndexName: os.Getenv("VIKINGDB_INDEX"), }) ctx := context.Background() countResponse, err := index.Aggregate(ctx, model.AggRequest{ Op: "count", GroupBy: stringPtr("category"), Order: model.ScalarOrderDesc, RecallBase: model.RecallBase{ Filter: model.MapStr{ "op": "range", "field": "price", "gte": 10.0, }, }, }) printResult("count", countResponse, err) sumResponse, err := index.Aggregate(ctx, model.AggRequest{ Op: "sum", GroupBy: stringPtr("category"), CalcValueOn: stringPtr("price"), Order: model.ScalarOrderDesc, }) printResult("sum", sumResponse, err) vectorResponse, err := index.Aggregate(ctx, model.AggRequest{ Op: "vector_weighted_sum", IDs: []interface{}{101, 102, 103}, Weights: []float64{0.2, 0.3, 0.5}, }) printResult("vector_weighted_sum", vectorResponse, err) }
| 场景 | 返回结果 |
|---|---|
全局 count 没有命中数据 | Agg["__TOTAL__"] 为 0。 |
分桶 count 没有命中数据 | Agg 为空。 |
全局 sum、avg、min、max 没有有效数值 | Agg["__TOTAL__"] 为 nil。 |
分桶 sum、avg、min、max 没有有效数值 | Agg 为空。 |
vector_weighted_sum 的 IDs 均未命中 | Vector 和 FoundIDs 为空,FoundCount 和 WeightSum 为 0。 |
sum、avg、min、max 不使用 0 表示空结果,因为 0 本身是合法的计算结果。
Filter 缩小统计范围,或选择低基数字段。vector_weighted_sum 的 IDs 不能包含重复主键;Weights 只能包含有限数值。vector_weighted_sum 不支持 Filter、GroupBy、CalcValueOn 和 Order。WeightSum。Vector[i] / WeightSum。当 FoundCount 或 WeightSum 为 0 时,不应直接做除法。