rag

根据你提供的代码和之前的上下文(如 collection_name = f"kb_{kb_id}"),在你的系统中,文档(Document)并不是一个 Collection

它们的关系层级如下:

1. 层级结构关系

  • 知识库 (Knowledge Base) = Weaviate Collection (集合)

    • 物理隔离:每个知识库对应 Weaviate 中的一个独立 Collection(表)。
    • 命名规则:kb_{knowledge_base_id}(例如 kb_1, kb_2)。
    • 区分方式:通过 Collection Name 区分。
  • 文档 (Document) = Collection 中的一组对象 (Objects)

    • 逻辑分组:一个文档被切分成多个“片段(Chunk)”,这些片段都存储在同一个 Collection 中。
    • 区分方式:通过 Metadata 字段 doc_id 区分。所有属于同一个文档的切片,都拥有相同的 doc_id
  • 片段 (Chunk/Segment) = Weaviate Object (单条数据)

    • 最小单位:这是真正存储向量(Vector)和文本(Content)的实体。
    • 区分方式:每个对象有唯一的 UUID,且通过 chunk_index 标记顺序。

2. 代码中的具体体现

在你的 WeaviateClient 代码中,这种结构非常清晰:

A. 知识库 (Collection) 的区分

create_collectionadd_documents 方法中,你需要传入 collection_name
在业务逻辑(之前的 indexing.py)中,你是这样调用的:

collection_name = f"kb_{knowledge_base_id}"  # 这里决定了知识库 = Collection
await weaviate.add_documents(collection_name, ...)

B. 文档 (Document) 的区分

add_documents 方法内部,你将文档的 ID 写入了属性(Property)中:

# add_documents 方法内
uuid = batch.add_object(
    properties={
        "content": doc.get("content", ""),
        
        # 👇 关键点:这是区分文档的字段
        "doc_id": doc.get("doc_id", ""), 
        
        "doc_name": doc.get("doc_name", ""),
        "chunk_index": doc.get("chunk_index", 0),
        # ...
    },
    vector=vec
)

3. 如何操作(增删改查)

基于这种结构,你的操作逻辑应该是这样的:

(1) 搜索整个知识库

不需要过滤,直接查对应的 Collection:

# 搜索知识库 ID 为 1 的所有内容
client.collections.get("kb_1").query.hybrid(query="...")

(2) 搜索特定文档

需要在搜索知识库的基础上,增加 doc_id 过滤器

# 搜索知识库 1 中,文档 ID 为 "doc_123" 的内容
filters = {"doc_id": "doc_123"} 
await weaviate.hybrid_search("kb_1", query="...", filters=filters)

(3) 删除一个文档

根据 doc_id 删除该文档下的所有切片:

# 从知识库 1 中删除文档 "doc_123"
filters = {"doc_id": "doc_123"}
await weaviate.delete_documents("kb_1", filters=filters)

(4) 删除整个知识库

直接删除 Collection:

# 删除知识库 1
await weaviate.delete_collection("kb_1")

4. 为什么要这样设计?

这种 "知识库=Collection, 文档=Tag" 的设计是 Weaviate 的最佳实践,原因如下:

  1. 搜索效率
    • Weaviate 的索引是基于 Collection 构建的。在同一个 Collection 内进行向量检索(HNSW)效率最高。
    • 跨 Collection 搜索非常麻烦且性能差。因为知识库通常是业务隔离的边界(比如“财务知识库”和“IT支持知识库”不应该混在一起搜),所以把知识库设为 Collection 是对的。
  2. 资源管理
    • 删除整个知识库时,delete_collection 是瞬间完成的(直接删除文件),比逐条删除数据快得多。
  3. 文档粒度
    • 如果把“文档”设为 Collection,会导致 Collection 数量爆炸(比如你有 1 万个文档,就有 1 万个 Collection),这会把数据库拖垮。Weaviate 建议 Collection 数量保持在可控范围内(几十到几百个)。
posted @ 2026-01-09 01:20  春水鸿鹄  阅读(4)  评论(0)    收藏  举报