一、背景介绍
在前面的文章中,我们已经通过 LangChain 的封装接口,完成了从 PDF 读取、文本分割、向量化到向量库存储的完整 RAG 索引构建流程。LangChain 的 Chroma 类提供了便捷的 add_documents 和 similarity_search 等方法,让我们无需关心底层细节就能快速上手。
但在实际开发和运维中,我们往往需要直接操作向量数据库------查看有哪些集合、每个集合有多少条记录、清理过期数据等。这些"管理型"操作如果也通过 LangChain 的封装层来做,就显得有些绕远了。
本文将基于 ChromaDB 原生 Python API,实现几个简单实用的管理工具:列出集合、查看记录数、删除集合。这些工具与 LangChain 的封装层操作的是同一个数据库文件,可以无缝混用。
二、方案分析:为什么需要原生 API?
2.1 LangChain 封装 vs 原生 API 的关系
LangChain 的 Chroma 类本质上是对 chromadb 原生库的薄封装。两者操作的是同一个持久化目录,可以互相访问对方写入的数据:
LangChain 封装层(之前代码)
↓ 底层调用
原生 chromadb(本次代码)
↓ 操作
磁盘文件(./chroma_langchain_db)
| 维度 | LangChain 封装 | 原生 chromadb |
|---|---|---|
| 定位 | 面向 RAG 应用开发,提供与 LLM 链式集成的便捷接口 | 面向数据库管理,提供更细粒度的操作能力 |
| 代码量 | 少,一行 add_documents 完成向量化+存储 |
多,需要手动处理客户端、集合、嵌入等 |
| 灵活性 | 受限于 LangChain 的抽象设计 | 完全暴露 ChromaDB 的全部能力 |
| 适用场景 | 快速构建检索链路 | 数据库运维、调试、管理工具开发 |
2.2 ChromaDB 核心概念映射
理解原生 API 前,先厘清 ChromaDB 的核心概念与关系型数据库的类比:
| ChromaDB 概念 | 关系型数据库类比 | 说明 |
|---|---|---|
Client |
数据库连接 | 连接到一个 Chroma 数据库实例 |
Collection |
表(Table) | 存储一组相关的向量和文档 |
Document |
行(Row) | 一条记录,包含文本、向量、元数据 |
embedding_function |
索引规则 | 定义如何将文本转换为向量 |
三、实操步骤:管理工具的实现
3.1 环境准备
确保已安装原生 chromadb 库(LangChain 的依赖通常已包含,但建议显式安装):
bash
uv add chromadb
# 或 pip install chromadb
3.2 工具一:列出所有集合
连接持久化数据库,遍历所有集合并输出名称和记录数:
python
import chromadb
def list_collections(db_path: str):
"""
列出向量库中的所有集合及其记录数。
Args:
db_path: ChromaDB 持久化目录路径(与 LangChain 的 persist_directory 对应)
"""
client = chromadb.PersistentClient(db_path) # 连接到磁盘上的数据库
collections = client.list_collections() # 获取所有集合对象
print(f"ChromaDB 向量库 {db_path} 共有 {len(collections)} 个 collection")
for i, collection in enumerate(collections):
print(f" Collection {i + 1}: {collection.name},共有 {collection.count()} 条记录")
# 查看之前 LangChain 代码创建的集合
list_collections("./chroma_langchain_db")
输出示例:
ChromaDB 向量库 ./chroma_langchain_db 共有 1 个 collection
Collection 1: example_collection,共有 516 条记录
关键 API 解析:
PersistentClient(path):连接到磁盘上的持久化数据库,与 LangChain 中persist_directory参数对应的是同一个路径;list_collections():返回所有集合对象(注意返回的是对象列表,而非仅名称列表);collection.count():返回该集合中的文档(向量)数量。
3.3 工具二:删除指定集合
清理不再需要的集合,释放磁盘空间:
python
def delete_collection(db_path: str, collection_name: str):
"""
删除指定名称的集合及其所有记录。
Args:
db_path: ChromaDB 持久化目录路径
collection_name: 要删除的集合名称
"""
try:
client = chromadb.PersistentClient(db_path)
client.delete_collection(collection_name)
print(f"✅ Collection '{collection_name}' 及其所有记录已删除")
except Exception as e:
print(f"❌ 删除 Collection '{collection_name}' 失败:{e}")
# 使用示例
delete_collection("./chroma_langchain_db", "example_collection")
异常处理说明:
- 若集合不存在,
delete_collection会抛出异常,需用try-except捕获; - 删除操作不可逆,集合内的所有向量、文档和元数据将一并清除。
四、验证效果:封装层与原生 API 的混用
以下代码演示了 LangChain 封装与原生 API 操作同一数据库的兼容性:
python
from langchain_chroma import Chroma
from langchain_ollama import OllamaEmbeddings
import chromadb
# 1. 用 LangChain 封装层写入数据
embeddings = OllamaEmbeddings(model="nomic-embed-text")
vector_store = Chroma(
collection_name="hybrid_test",
embedding_function=embeddings,
persist_directory="./chroma_langchain_db"
)
from langchain_core.documents import Document
vector_store.add_documents([
Document(page_content="Hello from LangChain", metadata={"source": "test"})
])
# 2. 用原生 API 读取并验证
client = chromadb.PersistentClient("./chroma_langchain_db")
collection = client.get_collection("hybrid_test")
print(f"通过原生 API 读取:{collection.name} 有 {collection.count()} 条记录")
# 输出:通过原生 API 读取:hybrid_test 有 1 条记录
# 3. 用原生 API 删除
client.delete_collection("hybrid_test")
print("已清理测试数据")
验证结论: LangChain 封装层与原生 chromadb 操作的是同一个底层存储,数据完全互通,可以根据场景灵活选择接口层级。
五、总结
本文实现了两个最基础的 ChromaDB 管理工具------列集合 和删集合 。它们的意义不仅在于功能本身,更在于建立一种认知:LangChain 是便捷的封装,但不应成为理解的屏障。当需要调试、运维或实现框架未覆盖的功能时,直接操作原生 API 是更直接、更可控的选择。
后续可以基于此扩展更多管理功能,如:
- 按条件查询集合内的具体文档内容
- 批量更新文档的元数据
- 导出/导入集合数据
- 监控集合的存储占用和索引性能