数据结构
Zvec 如何通过 collection、document、schema 和索引来组织数据。
Zvec 采用 Collection 和 Document 的结构来组织数据。
Collections
Collection 是用来存放 documents 的具名容器 — 类似于关系型数据库 (如 MySQL) 中的数据表,其中每个 document 对应表中的一行。Collection 用于存储、组织和查询数据。
每个 Collection 由一个 Schema 定义,Schema 描述了其包含的标量字段和向量及其类型和索引设置。
同一个 collection 中的所有 documents 都必须遵循相同的 schema。
Zvec 中的 collection schema 是动态的:你可以随时添加或删除标量字段和向量,无需重建 collection。
不支持跨 collection 查询:不支持 Join、Union 或多 collection 检索。请据此合理设计你的数据模型。
为什么要使用 Collection?
Collection 提供了隔离,确保每个业务场景都拥有独立的 schema 和索引配置。这种隔离既避免了不同业务之间的相互干扰,也让它们可以独立调整。
例如:
- 检索增强生成(RAG)collection 可能存储文本向量以及元数据 — 如标题、章节、源 URL 和最后更新时间戳。
- 图片搜索 collection 可以存储高维度的图片向量以及相关字段,如图片 ID、文件路径或描述。
持久化
-
每个 collection 独立持久化在磁盘上的专属目录中,从而在不同的业务场景之间提供隔离。
-
每个 collection 完全自包含于其目录中。这意味着你可以自由迁移 collection 的文件夹,只需提供正确的路径,Zvec 就能顺利加载它。
Documents
Document 是数据存储的基本单元 — 类似于关系型数据库表中的一条记录或一行。每个 document 都存在于一个 collection 中,并且必须符合该 collection 的 schema。
Document 的结构
Document 是由三个核心部分组成的结构化对象。
- 🔑
id:Document 的唯一字符串标识符,在 document 被写入后不可修改 - 📐
vectors:一组具名向量 - 🗂️
fields:一组具名标量 (非向量) 字段,可包含字符串、数值、布尔值或这些类型的数组
Document 示例
所有字段必须符合 schema 中声明的类型。向量必须匹配指定的类型(稠密或稀疏)和维度(例如,768维的向量字段不能接受512维的向量)。
数据类型
Zvec 实现了强类型的 schema 系统,并使用 DataType 枚举,其支持的类型可分为以下两类:
- 标量类型 — 字符串、整数、浮点数、布尔值以及这些类型的数组
- 向量类型 — 稠密向量和稀疏向量
数据写入阶段会执行类型安全检查: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 中:
你可以在创建 collection 时,通过在 schema 中为每个标量或向量指定 index_param 来定义索引。
或者,你也可以在 collection 创建好之后动态调用 create_index() 创建索引 — 此操作无需重新导入数据。
import zvec
# 定义 collection schema,包含一个标量字段和一个向量字段,且均通过 "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)