【向量数据库】Chunk和Document是什么关系以及原理?
全局元数据Document、实际内容分块Chunk;两者通过 `doc_uuid`(文档唯一标识符)建立 **一对多关系**:- 1 个 `Document` ➔ 对应 N 个 `Chunk`- 每个 `Chunk` 通过 `doc_uuid` 指向其所属的 `Document`
初始化 Weaviate 数据库中的 Document 和 Chunk 类
初始化 Weaviate 数据库中的 Document 和 Chunk 类。
它首先获取 Weaviate 客户端实例,然后定义 Chunk 和 Document 的模式。
如果 Document 类已存在,会询问用户是否重写。最后创建或更新模式,并在使用嵌入式数据库时停止它。
def init_schema(model: str = "gpt-3.5-turbo-16k"):
msg.divider("Creating Document and Chunk class")
client = setup_client()
chunk_schema = {
"classes": [
{
"class": "Chunk",
"description": "Chunks of Documentations",
"vectorizer": "text2vec-openai",
"moduleConfig": {
"generative-openai": {"model": model}
}, # gpt-4 / gpt-3.5-turbo
"properties": [
{
"name": "text",
"dataType": ["text"],
"description": "Content of the document",
},
{
"name": "doc_name",
"dataType": ["text"],
"description": "Document name",
},
{
"name": "doc_type",
"dataType": ["text"],
"description": "Document type",
},
{
"name": "doc_uuid",
"dataType": ["text"],
"description": "Document UUID",
"moduleConfig": {
"text2vec-openai": {
"skip": True, # skip:True排除非语义字段的向量化
"vectorizePropertyName": False, # 不参与向量化
}
},
},
{
"name": "chunk_id",
"dataType": ["number"],
"description": "Document chunk from the whole document",
"moduleConfig": {
"text2vec-openai": {
"skip": True,
"vectorizePropertyName": False, # 不参与向量化
}
},
},
],
}
]
}
document_schema = {
"classes": [
{
"class": "Document",
"description": "Documentation",
"properties": [
{
"name": "text",
"dataType": ["text"],
"description": "Content of the document",
},
{
"name": "doc_name",
"dataType": ["text"],
"description": "Document name",
},
{
"name": "doc_type",
"dataType": ["text"],
"description": "Document type",
},
{
"name": "doc_link",
"dataType": ["text"],
"description": "Link to document",
},
],
}
]
}
if client.schema.exists("Document"):
user_input = input(
"此文档已经存在,你想重写吗? (y/n): "
)
if user_input.strip().lower() == "y":
client.schema.delete_class("Document")
client.schema.delete_class("Chunk")
client.schema.create(document_schema)
client.schema.create(chunk_schema)
msg.good("'Document' and 'Chunk' schemas created")
else:
msg.warn("Skipped deleting Document and Chunk schema, nothing changed")
else:
client.schema.create(document_schema)
client.schema.create(chunk_schema)
msg.good("'Document' and 'Chunk' schemas created")
if client._connection.embedded_db:
msg.info("Stopping Weaviate Embedded")
client._connection.embedded_db.stop()
msg.info("Done")
在向量数据库中,Chunk 和 Document 的设计体现了 分块存储 和 元数据管理 的核心思想,以下是它们的关联关系和底层原理:
一、关系:父子层级结构
-
Document(文档):
表示完整的文档实体,存储 全局元数据(如文档名称、类型、链接等),是逻辑上的完整单位。 -
Chunk(分块):
表示文档的片段,存储 实际内容分块(如段落或句子)及其向量化结果,是物理上的检索单位。
关联方式:
通过 doc_uuid(文档唯一标识符)建立 一对多关系:
- 1 个
Document➔ 对应 N 个Chunk - 每个
Chunk通过doc_uuid指向其所属的Document
二、原理:分块存储与检索优化
1. 分块存储的动机
- 语义粒度控制:
长文档直接向量化会丢失细节(如 OpenAI 模型有 token 长度限制)。分块后,每个Chunk可独立向量化,保留局部语义。 - 检索效率:
直接检索文档级向量可能返回不相关内容(如匹配到文档开头但实际答案在结尾)。分块后,检索更精准。 - 资源优化:
更新部分内容时,只需重新处理相关Chunk,无需重构整个文档的向量。
2. 元数据与内容分离
- Document 的职责:
- 存储文档的 业务属性(如
doc_link用于溯源) - 提供全局视角(如统计某类文档的分块数量)
- 存储文档的 业务属性(如
- Chunk 的职责:
- 存储 可检索的内容(
text属性被向量化) - 附加分块级元数据(如
chunk_id记录片段顺序)
- 存储 可检索的内容(
3. 向量化与检索流程
# 伪代码示例
document = Document(doc_name="用户手册", doc_type="PDF", doc_link="https://example.com/manual")
chunks = [
Chunk(text="第一章:安装指南...", doc_uuid=document.uuid, chunk_id=1),
Chunk(text="第二章:配置参数...", doc_uuid=document.uuid, chunk_id=2)
]
# 向量化时:
for chunk in chunks:
chunk.vector = openai_embedding(chunk.text) # 使用 text2vec-openai 生成向量
# 检索时:
query = "如何安装软件?"
query_vector = openai_embedding(query)
results = weaviate.search_chunks(query_vector) # 返回最匹配的 Chunk
related_document = get_document_by_uuid(results[0].doc_uuid) # 通过 Chunk 找到原文档
三、设计影响与典型场景
1. 优势
- 精准检索:
直接命中相关内容片段(如用户提问“配置参数”时,仅返回第二章的Chunk)。 - 灵活更新:
新增文档时,只需插入新Chunk并关联到现有Document。 - 混合搜索:
结合向量搜索(语义匹配)和元数据过滤(如doc_type="PDF")。
2. 典型应用场景
- 问答系统:
通过Chunk检索答案片段,通过Document提供原文链接。 - 知识库管理:
统计某类文档(如doc_type="技术报告")的所有相关Chunk。 - 增量更新:
当文档修订时,仅更新变动的Chunk,无需全量重新向量化。
四、技术细节补充
-
向量化跳过非必要字段:
Chunk中的doc_uuid和chunk_id设置为skip: True,避免无意义的文本(如 UUID)污染向量表示。 -
生成式扩展:
通过generative-openai模块,可直接基于Chunk内容生成答案(如 GPT-3.5 补全技术)。 -
数据一致性:
删除Document时需级联删除其关联的Chunk(需业务层实现,Weaviate 不自动处理外键)。
总结
Chunk 是向量数据库的 检索主力,负责承载可搜索的语义片段;Document 是 业务逻辑单元,提供上下文管理和溯源能力。两者通过唯一标识符松耦合,兼顾检索效率与元数据管理,是处理长文本、构建语义搜索系统的标准模式。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)