数据结构
在 Zvec 中,数据以 Collection 和 Document 的形式进行组织。
Collection
Collection 是 Document 的命名容器 — 类似于关系型数据库(如 MySQL)中的表,其中每个 Document 对应表中的一行。Collection 用于存储、组织和查询数据。
每个 Collection 由一个 Schema 定义,Schema 描述了其包含的标量字段和向量及其类型和索引设置。
Collection 中的所有 Document 都遵循相同的 Schema。
Zvec 的 Schema 是动态的:你可以随时添加或删除标量字段和向量,无需重建 Collection。
不支持跨 Collection 查询:不支持 Join、Union 或多 Collection 搜索。请据此设计数据模型。
为什么使用 Collection?
Collection 通过隔离确保每个数据工作负载拥有独立的 Schema 和索引配置。这种分离避免了不相关用例之间的相互干扰,并允许各自独立演进。
例如:
- 检索增强生成(RAG)Collection 可能存储文本 Embedding 以及元数据 — 如标题、章节、来源 URL 和最后更新时间戳。
- 图片搜索 Collection 可以存储高维图片 Embedding 以及相关字段,如图片 ID、文件路径或描述。
持久化
-
每个 Collection 独立持久化在磁盘上的专属目录中,确保不同数据工作负载之间的隔离。
-
每个 Collection 完全自包含于其目录中。这意味着你可以迁移 Collection 的目录,只要提供正确的路径,Zvec 仍然能够打开它。
Document
Document 是数据存储的基本单元 — 类似于关系型数据库表中的一条记录或一行。每个 Document 存在于一个 Collection 中,并且必须符合该 Collection 的 Schema。
Document 结构
Document 是一个结构化对象,由三个核心部分组成。
- 🔑
id:Document 的唯一字符串标识符,插入后不可修改 - 📐
vectors:一组命名的向量 - 🗂️
fields:一组命名的标量(非向量)字段,可包含字符串、数字、布尔值或这些类型的数组
Document 示例
所有字段必须符合 Schema 中声明的类型。向量必须精确匹配指定的类型(稠密或稀疏)和维度(例如,768 维的稠密向量不能接受 512 维的向量)。
数据类型
Zvec 使用基于 DataType 枚举的强类型 Schema 系统。支持的类型分为两类:
- 标量类型 — 字符串、整数、浮点数、布尔值以及这些类型的数组
- 向量类型 — 用于向量 Embedding 的稠密或稀疏数值表示
类型安全在数据写入时强制执行:每个 Document 字段必须符合其对应声明的 DataType。
标量类型
-
基础类型
STRINGBOOLINT32INT64UINT32UINT64FLOATDOUBLE -
数组类型
ARRAY_STRINGARRAY_BOOLARRAY_INT32ARRAY_INT64ARRAY_UINT32ARRAY_UINT64ARRAY_FLOATARRAY_DOUBLE数组不能包含混合类型或嵌套结构。所有元素必须匹配声明的数组元素类型。
向量类型
-
稠密向量类型: 以固定长度的数值数组表示,例如
[0.1, -0.5, ..., 0.9]VECTOR_FP16VECTOR_FP32VECTOR_INT8 -
稀疏向量类型: 以整数索引到浮点值的映射表示,例如
{ 42: 0.85, 1024: 0.13 }SPARSE_VECTOR_FP32SPARSE_VECTOR_FP16
索引
索引在基本的标量字段和向量存储之上加速数据检索。在 Zvec 中:
- 每个向量字段都必须使用合适的向量索引建立索引,以启用相似度搜索。
- 标量字段可选择性地建立索引 — 但如果你计划在过滤查询中使用某个标量字段(例如
WHERE category = 'music'),应当为其构建倒排索引。
你可以在创建 Collection 时,通过在 Schema 中为每个字段或向量指定 index_param 来定义索引。
或者,你也可以在创建 Collection 后动态调用 create_index() 添加索引 — 无需重新导入数据。
import zvec
# Define the collection schema with one scalar field and one vector field, both
# configured with indexes via "index_param".
schema = zvec.CollectionSchema(
name="my_collection",
fields=[
zvec.FieldSchema(
name="price",
data_type=zvec.DataType.INT32,
index_param=zvec.InvertIndexParam(enable_range_optimization=True),
),
],
vectors=[
zvec.VectorSchema(
name="vector",
data_type=zvec.DataType.VECTOR_FP32,
dimension=256,
index_param=zvec.HnswIndexParam(metric_type=zvec.MetricType.COSINE),
),
],
)
collection = zvec.create_and_open(path="/path/to/my/collection", schema=schema)