ChromaDB Collections (集合管理)
Collection 设计这件事,很多人一开始不重视,后面最容易返工。因为一旦文档量上来,集合边界、id 规则和 metadata 结构都会直接影响检索质量和维护成本。
你可以把 Collection 理解成关系型数据库里的表,但在 RAG 项目里,它更像“检索边界”。边界划得清不清楚,决定了你后面要不要一直靠过滤条件补漏洞。
#1. 集合的基本操作
#创建与获取
python# 创建新集合,如果已存在则报错 collection = client.create_collection(name="test_name") # 如果不存在则创建,如果已存在则获取 collection = client.get_or_create_collection(name="test_name") # 仅获取已存在的集合 collection = client.get_collection(name="test_name") # 删除集合 client.delete_collection(name="test_name")
#2. 数据结构详解
当你向集合 add 数据时,可以包含以下四个部分:
ids(必填): 每个项的唯一字符串标识符。embeddings(可选): 如果你自己计算了向量,传到这里。documents(可选): 原始文本。如果没传 embeddings,Chroma 会根据这些文本自动生成。metadatas(可选): 键值对字典,用于后续的精细化过滤。
#读者导向建议
- 个人项目:先定一套稳定的 metadata 字段(如
source、topic、lang) - 团队项目:约定
id生成规则,避免多人写入冲突 - 生产项目:把删除策略和归档策略提前设计,不要等库变大后再补
这几条看着像管理问题,实际上都是检索问题。因为只要集合和 metadata 没定住,你的召回噪音就会越来越高。
#3. 更新与删除数据
python# 更新已存在的项 collection.update( ids=["id1"], metadatas=[{"status": "archived"}], ) # Upsert (存在则更新,不存在则添加) collection.upsert( ids=["id1", "id3"], documents=["新的内容", "新添加的内容"] ) # 根据 ID 删除 collection.delete(ids=["id1"]) # 根据元数据过滤删除 collection.delete(where={"status": "archived"})
#4. 强大的过滤查询 (Where)
Chroma 支持基于元数据和文档内容的复杂过滤。
#元数据过滤 (where)
pythonresults = collection.query( query_texts=["查询文本"], where={"source": "notion"}, # 仅搜索来源是 notion 的数据 n_results=5 )
一句轻松提醒:
没有 metadata 的向量库,就像没有标签的衣柜。
衣服都在,但早上赶时间时你只会怀疑人生。
我一般至少会先留 source、lang、doc_type、updated_at 这类字段。先别管以后会不会全用上,留接口总比后面重建库轻松。
#文档内容过滤 (where_document)
pythonresults = collection.query( query_texts=["查询文本"], where_document={"$contains": "重要"} # 仅搜索包含“重要”字样的文档 )
#5. 计算距离 (Distance Metrics)
你可以选择不同的数学方法来计算“相似度”:
l2: 平方 L2 范数(默认)。ip: 内积。cosine: 余弦相似度。
在创建集合时指定:
pythoncollection = client.create_collection( name="my_collection", metadata={"hnsw:space": "cosine"} )
别一开始就在距离度量上折腾太久。真实项目里,更常见的收益还是来自文档切块和 metadata 设计,而不是把 l2 和 cosine 来回换。
下一步:了解 Chroma 的核心——Embedding 模型自定义。