如何从FAISS向量库检索同一大文件拆分的所有文档?
关于FAISS VectorStore检索同一文件拆分文档的解决方案
问题解答
- 可以从FAISS中检索同一大文件拆分的所有文档,核心是给每个拆分后的文档添加原文件标识的元数据,以此作为关联依据。
- FAISS向量库核心依赖向量相似度完成检索,但LangChain封装的FAISS VectorStore支持结合元数据进行关联筛选——元数据是额外的检索维度,和向量相似度不冲突,可用来标记同一来源的文档。
代码实现(按PDF文件名检索并重构文本)
修改原有代码,重点是给拆分后的文档添加元数据,通过元数据过滤实现精准检索:
from langchain.embeddings.openai import OpenAIEmbeddings from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.document_loaders import PyPDFLoader from langchain.vectorstores import FAISS # 初始化嵌入模型 embeddings = OpenAIEmbeddings( deployment="embedding", model="text-embedding-ada-002", openai_api_base="https://test.openai.azure.com/", openai_api_type="azure", chunk_size=1 ) # 加载并拆分PDF文档,添加原文件名元数据 file_item = "目标文件名.pdf" # 替换为实际文件名 text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=50) loader = PyPDFLoader(f"data2/{file_item}") documents = loader.load() texts = text_splitter.split_documents(documents) # 给每个拆分后的文档添加原文件名元数据 source_filename = file_item for doc in texts: doc.metadata["source"] = source_filename # 用source字段标记原文件 # 构建FAISS向量库 db = FAISS.from_documents(documents=texts, embedding=embeddings) # 根据PDF文件名获取所有关联文档 def get_documents_by_filename(filename): # 利用元数据过滤检索所有该文件的文档 matched_docs = db.similarity_search("", filter={"source": filename}) return matched_docs # 重构原文件文本 def reconstruct_text_from_docs(documents): # 按文档页码排序,保证内容顺序与原PDF一致 sorted_docs = sorted(documents, key=lambda x: x.metadata.get("page", 0)) # 拼接所有文档内容 reconstructed_text = "\n".join([doc.page_content for doc in sorted_docs]) return reconstructed_text # 调用示例 target_filename = "目标文件名.pdf" matched_documents = get_documents_by_filename(target_filename) reconstructed_text = reconstruct_text_from_docs(matched_documents) # 输出或保存重构后的文本 print(reconstructed_text)
关键说明
- 元数据添加:拆分文档后给每个
Document对象的metadata字典添加自定义字段(如source)存储原文件名,这是关联同一文件拆分文档的核心。 - 元数据过滤:使用
similarity_search方法的filter参数,精准匹配元数据中的文件名,无需依赖向量相似度即可获取所有目标文档。 - 文本重构:按文档的
page元数据排序,确保拼接顺序与原PDF一致,避免内容错乱。
内容的提问来源于stack exchange,提问作者gabi
相关产品推荐
相关产品推荐

