聚合统计用于对索引中的数据做统计计算,适合在不拉取明细数据的情况下查看数据规模、字段分布和数值汇总结果,或对指定主键对应的向量做加权求和。
当前 aggregate 方法支持以下聚合算子:
| 聚合类型 | 支持算子 | 说明 |
|---|---|---|
| 标量计数聚合 | count | 统计命中数据量。设置 group_by 时按字段分桶;不设置时统计全局数量。 |
| 标量计算聚合 | sum、avg、min、max | 对 calc_value_on 指定的数值字段计算求和、平均值、最小值或最大值,也可按 group_by 分桶。 |
| 向量计算聚合 | vector_weighted_sum | 对 ids 对应的向量按 weights 加权求和。 |
标量聚合可通过 filter 缩小统计范围。group_by 对应 SQL 的 GROUP BY,filter 对应 SQL 的 WHERE。
对应的 V1 接口为:https://www.volcengine.com/docs/84313/1399339
| 功能 | V2 SDK | V1 SDK |
|---|---|---|
| 子索引 | 性能和易用性更强的分片能力研发中,敬请期待。 | 通过 partition 参数指定。 |
通过 IndexClient 调用聚合方法:
def aggregate( request: Union[AggRequest, Mapping[str, object]], *, request_options: Optional[RequestOptions] = None, ) -> AggResponse: ...
调用 client.index() 创建索引客户端时,需要指定以下定位参数:
| 参数名 | 类型 | 必选 | 说明 |
|---|---|---|---|
resource_id | str | 与 collection_name 二选一 | Collection 的资源 ID。 |
collection_name | str | 与 resource_id 二选一 | Collection 名称。 |
project_name | Optional[str] | 否 | 项目名称。通过 Collection 名称定位时可用于限定项目。 |
index_name | str | 是 | Index 名称。 |
AggRequest 包含以下字段:
| 参数名 | 类型 | 必选 | 说明 |
|---|---|---|---|
op | str | 是 | 聚合算子。支持 count、sum、avg、min、max、vector_weighted_sum。 |
filter | Optional[Mapping[str, Any]] | 否 | 过滤条件。仅标量聚合支持;语法与检索接口一致,不设置时聚合当前索引内的全部数据。 |
group_by | Optional[str] | 否 | 分桶字段。仅标量聚合支持;不设置时执行全局聚合。 |
calc_value_on | Optional[str] | 条件必选 | 标量计算字段。op 为 sum、avg、min 或 max 时必填。 |
order | Optional[str] | 否 | 分桶结果排序方向,支持 desc 和 asc,默认 desc。仅分桶标量聚合生效。 |
ids | Optional[Sequence[Any]] | 条件必选 | 参与向量加权求和的主键列表。op 为 vector_weighted_sum 时必填,最多 2000 个。元素类型需与 Collection 主键类型一致。 |
weights | Optional[Sequence[float]] | 条件必选 | 与 ids 一一对应的权重列表。op 为 vector_weighted_sum 时必填,长度必须与 ids 相同。 |
field 是 group_by 的已废弃兼容字段,新代码应使用 group_by。cond 是旧版分桶计数的兼容字段,新代码不建议使用。
过滤条件的结构和支持的算子参见检索公共参数。
op | 必填参数 | 可选参数 | 说明 |
|---|---|---|---|
count | 无 | group_by、filter、order | 统计全局数据量或按字段分桶计数。 |
sum | calc_value_on | group_by、filter、order | 对指定数值字段求和。 |
avg | calc_value_on | group_by、filter、order | 对指定数值字段求平均值。 |
min | calc_value_on | group_by、filter、order | 返回指定数值字段的最小值。 |
max | calc_value_on | group_by、filter、order | 返回指定数值字段的最大值。 |
vector_weighted_sum | ids、weights | 无 | 对指定主键对应的向量做加权求和。 |
字段和索引要求:
| 参数 | 支持的字段类型 | 索引要求 |
|---|---|---|
group_by | string、int64、bool | 字段需要已建立枚举索引。 |
calc_value_on | int64、float32 | 字段需要已建立范围索引。 |
使用 count 时,索引中需要至少存在一个可用于聚合的标量索引字段。使用 vector_weighted_sum 时,Collection 需要包含向量字段,或在创建 Collection 时配置 Vectorize。
方法返回 AggResponse:
| 字段 | 类型 | 说明 |
|---|---|---|
request_id | Optional[str] | 请求链路 ID,可用于问题排查。 |
code | Optional[str] | 响应状态码。 |
message | Optional[str] | 响应信息。 |
api | Optional[str] | 实际调用的 API 名称。 |
result | Optional[AggResult] | 聚合结果。 |
AggResult 结构:
| 字段 | 类型 | 说明 |
|---|---|---|
op | Optional[str] | 本次执行的聚合算子。 |
group_by | Optional[str] | 分桶字段。全局标量聚合时为 __NONE__。 |
calc_value_on | Optional[str] | 标量计算字段,仅 sum、avg、min、max 返回。 |
agg | Dict[str, Any] | 标量聚合结果。全局聚合使用 __TOTAL__ 作为结果键。 |
vector_weighted_sum | Optional[VectorWeightedSumResult] | 向量加权求和结果,仅 vector_weighted_sum 返回。 |
agg 中的 value 类型取决于算子和计算字段:
| 算子 | 结果类型 |
|---|---|
count | int。 |
sum、min、max | calc_value_on 为 int64 时返回 int,为 float32 时返回 float。 |
avg | float。 |
VectorWeightedSumResult 结构:
| 字段 | 类型 | 说明 |
|---|---|---|
vector | List[float] | 加权求和后的向量。 |
found_ids | List[Any] | 实际命中并参与计算的主键列表,顺序与请求中的 ids 一致。 |
found_count | Optional[int] | 实际命中并参与计算的主键数量。 |
weight_sum | Optional[float] | 实际参与计算的权重和,未命中主键对应的权重不计入。 |
以下示例分别执行分桶计数、分桶求和和向量加权求和。运行前请配置 VIKINGDB_AK、VIKINGDB_SK、VIKINGDB_HOST、VIKINGDB_REGION、VIKINGDB_COLLECTION 和 VIKINGDB_INDEX 环境变量。
import json import os from vikingdb import IAM from vikingdb.vector import AggRequest, VikingDB client = VikingDB( host=os.environ["VIKINGDB_HOST"], region=os.environ["VIKINGDB_REGION"], auth=IAM( ak=os.environ["VIKINGDB_AK"], sk=os.environ["VIKINGDB_SK"], ), scheme="https", timeout=30, ) index = client.index( collection_name=os.environ["VIKINGDB_COLLECTION"], index_name=os.environ["VIKINGDB_INDEX"], ) count_response = index.aggregate( AggRequest( op="count", group_by="category", order="desc", filter={ "op": "range", "field": "price", "gte": 10.0, }, ) ) print( "count", count_response.request_id, json.dumps(count_response.result.agg, ensure_ascii=False), ) sum_response = index.aggregate( AggRequest( op="sum", calc_value_on="price", group_by="category", order="desc", ) ) print( "sum", sum_response.request_id, json.dumps(sum_response.result.agg, ensure_ascii=False), ) vector_response = index.aggregate( AggRequest( op="vector_weighted_sum", ids=[101, 102, 103], weights=[0.2, 0.3, 0.5], ) ) weighted_sum = vector_response.result.vector_weighted_sum print( "vector_weighted_sum", vector_response.request_id, weighted_sum.model_dump(by_alias=True), )
| 场景 | 返回结果 |
|---|---|
全局 count 没有命中数据 | agg["__TOTAL__"] 为 0。 |
分桶 count 没有命中数据 | agg 为空字典。 |
全局 sum、avg、min、max 没有有效数值 | agg["__TOTAL__"] 为 None。 |
分桶 sum、avg、min、max 没有有效数值 | agg 为空字典。 |
vector_weighted_sum 的 ids 均未命中 | vector 和 found_ids 为空,found_count 和 weight_sum 为 0。 |
sum、avg、min、max 不使用 0 表示空结果,因为 0 本身是合法的计算结果。
filter 缩小统计范围,或选择低基数字段。vector_weighted_sum 的 ids 不能包含重复主键;weights 只能包含有限数值。vector_weighted_sum 不支持 filter、group_by、calc_value_on 和 order。weight_sum。[value / weight_sum for value in vector]。当 found_count 或 weight_sum 为 0 时,不应直接做除法。