Редактировать kb_service.py
This commit is contained in:
@@ -166,16 +166,7 @@ class KBService:
|
||||
update_if_exists: bool = True
|
||||
) -> Tuple[int, int]:
|
||||
"""
|
||||
Индексирует документ в базу знаний с транзакционностью и атомарным обновлением:
|
||||
1. Если документ уже существует в комнате и update_if_exists=True,
|
||||
запоминаем старый doc_id, но НЕ удаляем его сразу.
|
||||
2. Создаём новую запись с indexed=False и новым doc_id.
|
||||
3. Разбиваем на чанки, получаем эмбеддинги, загружаем в Qdrant.
|
||||
4. Если успешно – обновляем indexed=True у новой записи.
|
||||
5. Удаляем старый документ (если он был) из Qdrant и PostgreSQL.
|
||||
6. При ошибке – оставляем старый документ нетронутым, новую запись удаляем (или оставляем с indexed=False для диагностики).
|
||||
|
||||
Это гарантирует, что в любой момент времени либо старая версия доступна, либо новая.
|
||||
Индексирует документ в базу знаний с сохранением исходного текста в БД.
|
||||
"""
|
||||
source_name = title if title else file_name
|
||||
doc_meta = metadata or {}
|
||||
@@ -184,7 +175,7 @@ class KBService:
|
||||
|
||||
old_doc_id = None
|
||||
|
||||
# ---- 1. Поиск существующего документа в комнате (если нужно обновление) ----
|
||||
# ---- 1. Поиск существующего документа в комнате ----
|
||||
if update_if_exists and room_jid and not is_global:
|
||||
existing = await self.db.find_document_by_name_and_room(source_name, room_jid)
|
||||
if existing:
|
||||
@@ -195,7 +186,7 @@ class KBService:
|
||||
return old_doc_id, 0
|
||||
logger.info(f"Обновление документа {source_name} в комнате {room_jid}: старая версия doc_id={old_doc_id}")
|
||||
|
||||
# ---- 2. Создание НОВОЙ записи в PostgreSQL с indexed=False ----
|
||||
# ---- 2. Создание НОВОЙ записи в PostgreSQL с indexed=False и сохранением текста ----
|
||||
new_doc_id = await self.db.add_document(
|
||||
source_name=source_name,
|
||||
owner_jid=user_jid,
|
||||
@@ -204,7 +195,8 @@ class KBService:
|
||||
metadata=doc_meta,
|
||||
room_jid=room_jid,
|
||||
file_hash=file_hash,
|
||||
indexed=False # начальное состояние – не проиндексирован
|
||||
indexed=False,
|
||||
file_text=file_text # <-- сохраняем исходный текст
|
||||
)
|
||||
logger.info(f"Создана новая запись документа doc_id={new_doc_id} для {source_name}")
|
||||
|
||||
@@ -231,7 +223,7 @@ class KBService:
|
||||
|
||||
sparse_vectors = await self.embedding.embed_sparse_batch(chunks)
|
||||
|
||||
# ---- 5. Сохранение чанков в Qdrant (обёрнуто в to_thread) ----
|
||||
# ---- 5. Сохранение чанков в Qdrant ----
|
||||
chunk_count = 0
|
||||
success = True
|
||||
try:
|
||||
@@ -269,7 +261,6 @@ class KBService:
|
||||
# ---- 6. Если успешно – обновляем флаг indexed у НОВОЙ записи ----
|
||||
if success and chunk_count > 0:
|
||||
await self.db.update_document_indexed(new_doc_id, True)
|
||||
# Для личных документов предоставляем доступ владельцу
|
||||
if not is_global and not room_jid:
|
||||
await self.db.add_access(new_doc_id, user_jid)
|
||||
logger.info(f"Новый документ {source_name} (doc_id={new_doc_id}) проиндексирован, чанков: {chunk_count}")
|
||||
@@ -277,15 +268,11 @@ class KBService:
|
||||
# ---- 7. Удаляем СТАРЫЙ документ (если был) ----
|
||||
if old_doc_id is not None:
|
||||
logger.info(f"Удаление старой версии документа doc_id={old_doc_id}")
|
||||
# Удаление из Qdrant
|
||||
await asyncio.to_thread(self.qdrant.delete_by_doc_id, old_doc_id)
|
||||
# Удаление из PostgreSQL (включая права доступа)
|
||||
await self.db.delete_documents_by_ids([old_doc_id])
|
||||
logger.info(f"Старая версия doc_id={old_doc_id} удалена")
|
||||
else:
|
||||
# Не удалось загрузить все чанки – оставляем новую запись с indexed=False для диагностики
|
||||
logger.error(f"Документ {source_name} (doc_id={new_doc_id}) не проиндексирован (чанков: {chunk_count})")
|
||||
# Старый документ (если был) остаётся нетронутым
|
||||
|
||||
return new_doc_id, chunk_count
|
||||
|
||||
|
||||
Reference in New Issue
Block a user