sqlite fts5关键词数据库 和chroma向量数据库目前都是以删除为主,更新就是删除再加上上传。且二者都以文件路径为ID,同一路径只能插入一次,更新需要删除。当然重建是万无一失的,在10000文件一下,重建可以在10分钟以内完成。
SQLITE FTS5
使用官方默认工具插入:
from llama_index.core import SimpleDirectoryReader
from llama_index.retrievers.sqlite_ft import SQLiteFTSRetriever
from llama_index.core.query_engine import RetrieverQueryEngine
# 1. 读取文档
documents = SimpleDirectoryReader("data").load_data()
# 2. 建/载 FTS5 倒排(单文件 gov_docs.db)
sqlite_retriever = SQLiteFTSRetriever(
db_path="gov_docs.db",
docs=documents, # 第一次会自动建表;第二次直接复用
top_k=5
)
使用官方默认的SQLiteFTSRetriever 会创建一个documes表 id为文件路径路径:
所以你需要使用SQL语句去删除该文件。
-- 查看一下
SELECT id, title FROM documents WHERE id = '/home/you/project/data/obsolete.pdf';
-- 确认无误后删掉
DELETE FROM documents WHERE id = '/home/you/project/data/obsolete.pdf';
更新的化再执行插入:
# 1. 读取文档
documents = SimpleDirectoryReader("data").load_data()
# 2. 建/载 FTS5 倒排(单文件 gov_docs.db)
sqlite_retriever = SQLiteFTSRetriever(
db_path="gov_docs.db",
docs=documents, # 第一次会自动建表;第二次直接复用
top_k=5
)
Chroma向量数据库
代码如下:
# 1. 安装依赖
# pip install llama-index llama-index-vector-stores-chroma llama-index-embeddings-ollama chromadb
import chromadb
from llama_index.core import VectorStoreIndex, StorageContext, SimpleDirectoryReader
from llama_index.vector_stores.chroma import ChromaVectorStore
from llama_index.embeddings.ollama import OllamaEmbedding # 关键替换
# 2. 初始化 Chroma
chroma_client = chromadb.PersistentClient(path="./chroma_db")
collection = chroma_client.get_or_create_collection("ollama_embed")
# 3. 指定 Ollama 提供的向量模型
embed_model = OllamaEmbedding(
model_name="nomic-embed-text", # 也可换成 mxbai-embed-large、snowflake-arctic-embed 等
base_url="http://localhost:11434", # Ollama 默认地址
)
# 4. 构建 vector_store & storage_context
vector_store = ChromaVectorStore(chroma_collection=collection)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
# 5. 加载文档并一次性向量化入库
documents = SimpleDirectoryReader("./data").load_data()
index = VectorStoreIndex.from_documents(
documents,
storage_context=storage_context,
embed_model=embed_model,
show_progress=True
)
# 6. 验证查询
query_engine = index.as_query_engine(similarity_top_k=3)
print(query_engine.query("你的问题"))
如果使用删除 那么需要调用 collection.delete(ids=[file_path])这个方法,但是Chroma 里的 ids 自然就是“路径+序号”,所以需要先找到文件的ids。
matched_ids = []
# 删除的ids的chunks列表默认为空 防止错误
# 1. 一次性把 collection 里所有记录拉回
all_existing = collection.get(include=["metadatas"]) # 默认只返回 ids,加 include 才有 metadata
# 2. 过滤出你要的文件路径
target_path = "/home/you/project/data/obsolete.pdf"
matched_ids = [ _id
for _id, meta in zip(all_existing["ids"], all_existing["metadatas"])
if meta.get("file_path") == target_path ] # 这里字段名必须与你当初存的一致
# 3. 打印确认
print("待删除 IDs:", matched_ids)
# 4. 真正删除 (删除列表)
if matched_ids:
collection.delete(ids=matched_ids)
#循环显示通读的代码:找到 matched_ids
for _id, meta in zip(all_existing["ids"], all_existing["metadatas"]):
print(f"检查 ID: {_id}, metadata: {meta}") # 每一步都打印,看得一清二楚
if meta.get("file_path") == target_path:
matched_ids.append(_id)
print(f" --> 命中,加入待删列表")
else:
print(f" --> 不匹配,跳过")
跟新的化再执行插入:
documents = SimpleDirectoryReader("./data").load_data()
index = VectorStoreIndex.from_documents(
documents,
storage_context=storage_context,
embed_model=embed_model,
show_progress=True
)