ChromaDB配置:如何设置每页一个ID以支持按文件名删除文件
解决方案
要实现「每页对应一个标识(方便按文件名批量删除)」的需求,你需要调整文档加载、分块和入库的逻辑,核心是给每个分块绑定文件名+页码的元数据,同时可自定义分块ID来关联所属页面。以下是修改后的代码:
1. 调整文档加载与分块逻辑
修改load_documents函数,确保按页加载PDF,并给每个页面(及后续分块)添加文件名和页码元数据:
def load_documents(): docs = [] for file in os.listdir(FOLDER_PATH): if file.endswith('.pdf'): pdf_path = FOLDER_PATH + "/" + file # 按页加载PDF,每个页面生成一个Document对象 loader = UnstructuredLoader(pdf_path, mode="pages") page_docs = loader.load() # 给每个页面添加文件名元数据 for doc in page_docs: doc.metadata["filename"] = file # UnstructuredLoader默认会给页面添加page_number元数据,无需额外处理 docs.extend(page_docs) docs = filter_complex_metadata(docs) text_splitter = RecursiveCharacterTextSplitter(chunk_size=800, chunk_overlap=200) # 分块时会自动继承原页面的元数据(filename、page_number) chunks = text_splitter.split_documents(docs) return chunks
2. 自定义分块ID(可选)
如果希望每个页面的分块都关联到同一个页面级标识,可以给每个分块生成包含文件名+页码的唯一ID:
def populate_database(docs): db = Chroma(persist_directory=CHROMA_PATH, embedding_function=OllamaEmbeddings(model=embed_model)) # 为每个分块生成自定义ID ids = [] for idx, doc in enumerate(docs): filename = doc.metadata.get("filename", "unknown") page_num = doc.metadata.get("page_number", 0) # 生成唯一ID,格式:文件名_页码_分块序号 chunk_id = f"{filename}_page_{page_num}_chunk_{idx}" ids.append(chunk_id) # 带自定义ID入库 db.add_documents(docs, ids=ids) return db
3. 按文件名批量删除
现在可以通过文件名过滤,删除该文件对应的所有分块:
def delete_by_filename(filename): db = Chroma(persist_directory=CHROMA_PATH, embedding_function=OllamaEmbeddings(model=embed_model)) # 按filename元数据过滤删除 db.delete(where={"filename": filename})
关键说明
- 用
mode="pages"加载PDF时,UnstructuredLoader会自动给每个页面添加page_number元数据,结合手动添加的filename,可以精准定位每个分块的来源。 - Chroma要求每个document(分块)必须有唯一ID,因此无法让多个分块共用同一个页面ID,但通过自定义ID和元数据,可以实现按页面或文件名的批量管理。
- 删除时使用
where参数过滤元数据,无需手动维护ID列表,更灵活可靠。
内容的提问来源于stack exchange,提问作者user27852598
相关产品推荐
相关产品推荐

