You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在LangChain的PGVector中筛选最新文件的查询结果

基于LangChain和PGVector筛选最新上传文件的实现方案

核心逻辑

文件以timestamp_file_name格式存储,需从文件名提取时间戳作为元数据存入PGVector,查询时优先筛选时间戳最大的文档(即最新上传文件)的匹配内容。

步骤1:存储文档时注入时间戳元数据

上传并加载文档时,从文件名解析时间戳,将其作为元数据附加到每个Document对象中:

import os
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter

def load_and_store_document(auth_id, openai_key, file_path):
    # 从文件名提取时间戳
    filename = os.path.basename(file_path)
    timestamp = int(filename.split("_")[0])
    
    # 加载并拆分文档
    loader = PyPDFLoader(file_path)
    documents = loader.load()
    text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
    split_docs = text_splitter.split_documents(documents)
    
    # 为每个文档块添加时间戳元数据
    for doc in split_docs:
        doc.metadata.update({"timestamp": timestamp, "source": filename})
    
    # 存入PGVector
    vector_store = get_vector_store(auth_id, openai_key)
    vector_store.add_documents(split_docs)

步骤2:PGVector检索时筛选最新文件

有两种实现方式:

方式一:先查询最大时间戳,再过滤检索

先通过PGVector的底层连接查询当前集合下的最大时间戳,再以此为条件筛选文档:

import psycopg2
from psycopg2.extras import RealDictCursor

def get_latest_timestamp(auth_id):
    conn = psycopg2.connect(CONNECTION_STRING)
    cursor = conn.cursor(cursor_factory=RealDictCursor)
    # 查询当前collection的最大时间戳
    cursor.execute("""
        SELECT MAX(metadata->>'timestamp') as max_ts 
        FROM langchain_pg_embedding 
        WHERE collection_id = (SELECT uuid FROM langchain_pg_collection WHERE name = %s)
    """, (auth_id,))
    result = cursor.fetchone()
    conn.close()
    return int(result['max_ts']) if result['max_ts'] else None

# 获取最新时间戳
latest_ts = get_latest_timestamp(auth_id)

# 构建检索器:仅筛选最新时间戳的文档
retriever = vector_store.as_retriever(
    search_type=SEARCH_TYPE,
    search_kwargs={
        **SEARCH_KWARGS,
        "filter": {"timestamp": latest_ts}
    }
)

方式二:检索后过滤最新文件内容

若需先获取所有匹配文档再筛选,可在返回结果后按时间戳分组,保留最新文件的内容:

chain_response = chain(user_input)

# 提取来源文档,按文件分组并筛选最新文件
source_docs = chain_response['source_documents']
# 按文件名分组,记录每个文件的时间戳
file_ts_map = {}
for doc in source_docs:
    filename = doc.metadata['source']
    ts = doc.metadata['timestamp']
    if filename not in file_ts_map or ts > file_ts_map[filename]:
        file_ts_map[filename] = ts

# 找到时间戳最大的文件
latest_file = max(file_ts_map, key=file_ts_map.get)
# 过滤出仅来自最新文件的文档
latest_docs = [doc for doc in source_docs if doc.metadata['source'] == latest_file]

# 重新生成基于最新文件的回答
from langchain.chains.qa_with_sources import load_qa_with_sources_chain

refined_chain = load_qa_with_sources_chain(llm, chain_type="stuff")
refined_response = refined_chain({
    "input_documents": latest_docs,
    "question": user_input
}, return_only_outputs=True)

步骤3:调整RetrievalQA链配置

将上述构建的带筛选条件的检索器替换原链中的检索器:

chain = RetrievalQAWithSourcesChain.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=retriever,  # 使用带最新时间戳筛选的检索器
    chain_type_kwargs=chain_type_kwargs,
    return_source_documents=True,
    memory=window_memory
)
chain_response = chain(user_input)

内容的提问来源于stack exchange,提问作者Andrea Bency

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 22:35:42