|
@@ -31,14 +31,23 @@ def _save_sync_state(state: dict):
|
|
|
|
|
|
|
|
|
|
|
|
|
def _delete_by_prefix(vectorstore, prefix: str):
|
|
def _delete_by_prefix(vectorstore, prefix: str):
|
|
|
|
|
+ """删除指定 source 的所有旧块。
|
|
|
|
|
+
|
|
|
|
|
+ 修复: 原实现 vectorstore.get() 会拉取整个 collection (数百万条 embedding)
|
|
|
|
|
+ 到内存, 导致 gunicorn worker OOM 反复重启。改为按 metadata where 过滤
|
|
|
|
|
+ 只取目标 source 的 ids 再删除, 内存占用与数据总量无关。
|
|
|
|
|
+ """
|
|
|
try:
|
|
try:
|
|
|
- existing = vectorstore.get()
|
|
|
|
|
- ids = [i for i in existing.get("ids", []) if i.startswith(prefix)]
|
|
|
|
|
|
|
+ collection = vectorstore._collection
|
|
|
|
|
+ existing = collection.get(where={"source": prefix}, include=[])
|
|
|
|
|
+ ids = existing.get("ids", []) or []
|
|
|
if ids:
|
|
if ids:
|
|
|
- vectorstore.delete(ids)
|
|
|
|
|
- logger.info("已删除前缀 %s 的 %d 个旧块", prefix, len(ids))
|
|
|
|
|
|
|
+ collection.delete(ids=ids)
|
|
|
|
|
+ logger.info("已删除 source=%s 的 %d 个旧块", prefix, len(ids))
|
|
|
|
|
+ else:
|
|
|
|
|
+ logger.info("无 source=%s 旧块可删除", prefix)
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
|
- logger.warning("删除前缀 %s 旧块失败: %s", prefix, e)
|
|
|
|
|
|
|
+ logger.warning("删除 source=%s 旧块失败: %s", prefix, e)
|
|
|
|
|
|
|
|
|
|
|
|
|
def _build_chunks(splitter, items: list[dict], source: str) -> list[Document]:
|
|
def _build_chunks(splitter, items: list[dict], source: str) -> list[Document]:
|