如何通过LangChain实现ChromaDb单文档按需添加(去重)
实现单个文档校验并添加到ChromaDb的方案
核心思路
要实现单次添加单个文档并校验存在性,关键是给每个文档分配唯一标识(比如文件名、内容哈希),然后通过ChromaDb的查询接口验证该标识是否已存在,仅当不存在时执行嵌入和添加操作。
具体实现步骤与代码示例
以下是完整的可运行代码,基于LangChain和ChromaDb的常用版本:
1. 导入依赖库
from langchain.document_loaders import PyPDFLoader # 以PDF为例,可替换为其他加载器 from langchain.embeddings.openai import OpenAIEmbeddings from langchain.vectorstores import Chroma import hashlib import os
2. 定义生成文档唯一标识的函数
这里以文档内容哈希作为唯一标识(也可以用文件名,适合文件名唯一的场景):
def get_document_unique_id(doc): # 将文档内容转为字符串,生成SHA256哈希作为唯一ID content = doc.page_content.encode('utf-8') return hashlib.sha256(content).hexdigest()
3. 校验文档是否存在并添加的核心函数
def add_single_document_if_not_exists(doc_path, persist_directory="./chroma_db"): # 1. 加载单个文档 loader = PyPDFLoader(doc_path) docs = loader.load() # 单个文档取第一个元素(如果加载器返回多个页,可根据需求调整) doc = docs[0] # 2. 生成唯一ID doc_id = get_document_unique_id(doc) # 3. 连接ChromaDb embeddings = OpenAIEmbeddings() # 需配置OPENAI_API_KEY环境变量 db = Chroma( persist_directory=persist_directory, embedding_function=embeddings ) # 4. 校验文档是否存在 existing_docs = db.get(ids=[doc_id]) if existing_docs['ids']: print(f"文档{doc_path}已存在,跳过添加") return # 5. 不存在则添加文档 db.add_documents(documents=[doc], ids=[doc_id]) db.persist() print(f"文档{doc_path}已成功添加到ChromaDb")
4. 调用示例
# 替换为你的单个文档路径 add_single_document_if_not_exists("./example_document.pdf")
关键细节说明
- 唯一标识的选择:如果文件名全局唯一,可直接用
os.path.basename(doc_path)作为ID,比内容哈希更高效;如果文件名可能重复,必须用内容哈希保证唯一性。 - ChromaDb的查询方式:除了通过
ids查询,也可以用db.similarity_search_with_score结合文档元数据(比如文件名)进行模糊校验,但精准度不如唯一ID。 - 嵌入模型替换:如果不想用OpenAI的嵌入,可替换为本地模型,比如
HuggingFaceEmbeddings,只需修改embeddings的初始化代码。 - 多页文档处理:如果加载的文档包含多个页面(比如PDF的多页),可循环处理每一页,给每页生成独立ID,或者合并为单个文档后生成ID,根据业务需求调整。
内容的提问来源于stack exchange,提问作者user791793
相关产品推荐
相关产品推荐

