Редактировать kb_service.py
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
- Поиск релевантной информации по запросу (семантический поиск в Qdrant с фильтром по room_jid).
|
- Поиск релевантной информации по запросу (семантический поиск в Qdrant с фильтром по room_jid).
|
||||||
- Управление доступом к документам (личные / глобальные / комнатные).
|
- Управление доступом к документам (личные / глобальные / комнатные).
|
||||||
- Поддержка обновления версий документов в комнатах (атомарное обновление: сначала создаётся новая версия, затем удаляется старая).
|
- Поддержка обновления версий документов в комнатах (атомарное обновление: сначала создаётся новая версия, затем удаляется старая).
|
||||||
|
- Добавлен метод reindex_failed_documents для повторной индексации документов с indexed=False.
|
||||||
|
|
||||||
Добавлена транзакционность индексации через флаг indexed в PostgreSQL.
|
Добавлена транзакционность индексации через флаг indexed в PostgreSQL.
|
||||||
ВСЕ ВЫЗОВЫ QDRANT ОБЁРНУТЫ В asyncio.to_thread ДЛЯ ПРЕДОТВРАЩЕНИЯ БЛОКИРОВКИ EVENT LOOP.
|
ВСЕ ВЫЗОВЫ QDRANT ОБЁРНУТЫ В asyncio.to_thread ДЛЯ ПРЕДОТВРАЩЕНИЯ БЛОКИРОВКИ EVENT LOOP.
|
||||||
@@ -226,7 +227,6 @@ class KBService:
|
|||||||
dense_vectors = await self.embedding.embed_batch(chunks)
|
dense_vectors = await self.embedding.embed_batch(chunks)
|
||||||
if dense_vectors is None or len(dense_vectors) != len(chunks):
|
if dense_vectors is None or len(dense_vectors) != len(chunks):
|
||||||
logger.error(f"Не удалось получить dense-эмбеддинги для документа {new_doc_id}, оставляем indexed=False")
|
logger.error(f"Не удалось получить dense-эмбеддинги для документа {new_doc_id}, оставляем indexed=False")
|
||||||
# Можно удалить новую запись, но оставим для диагностики
|
|
||||||
return new_doc_id, 0
|
return new_doc_id, 0
|
||||||
|
|
||||||
sparse_vectors = await self.embedding.embed_sparse_batch(chunks)
|
sparse_vectors = await self.embedding.embed_sparse_batch(chunks)
|
||||||
@@ -289,6 +289,61 @@ class KBService:
|
|||||||
|
|
||||||
return new_doc_id, chunk_count
|
return new_doc_id, chunk_count
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# Повторная индексация (для reindex_worker)
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
|
||||||
|
async def reindex_failed_documents(self, batch_size: int = 10) -> None:
|
||||||
|
"""
|
||||||
|
Переиндексирует документы с indexed=False.
|
||||||
|
Использует метаданные для восстановления текста.
|
||||||
|
"""
|
||||||
|
import datetime
|
||||||
|
cutoff = datetime.datetime.now() - datetime.timedelta(days=7)
|
||||||
|
async with self.db.pool.acquire() as conn:
|
||||||
|
rows = await conn.fetch(
|
||||||
|
"""
|
||||||
|
SELECT id, source_name, owner_jid, room_jid, is_global, metadata, file_hash
|
||||||
|
FROM documents
|
||||||
|
WHERE indexed = FALSE
|
||||||
|
AND upload_time > $1
|
||||||
|
LIMIT $2
|
||||||
|
""",
|
||||||
|
cutoff,
|
||||||
|
batch_size
|
||||||
|
)
|
||||||
|
if not rows:
|
||||||
|
return
|
||||||
|
|
||||||
|
logger.info(f"Найдено {len(rows)} документов для переиндексации")
|
||||||
|
|
||||||
|
for row in rows:
|
||||||
|
doc_id = row['id']
|
||||||
|
metadata = row.get('metadata') or {}
|
||||||
|
file_text = metadata.get('file_text')
|
||||||
|
if not file_text:
|
||||||
|
logger.error(f"Документ {doc_id} не содержит текста для переиндексации, пропускаем")
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
doc_id_new, chunk_count = await self.add_document(
|
||||||
|
file_name=row['source_name'],
|
||||||
|
file_text=file_text,
|
||||||
|
user_jid=row['owner_jid'],
|
||||||
|
is_global=row['is_global'],
|
||||||
|
title=row['source_name'],
|
||||||
|
metadata=metadata,
|
||||||
|
room_jid=row['room_jid'],
|
||||||
|
file_hash=row['file_hash'],
|
||||||
|
update_if_exists=True
|
||||||
|
)
|
||||||
|
if chunk_count > 0:
|
||||||
|
logger.info(f"Документ {doc_id} успешно переиндексирован (новый doc_id={doc_id_new})")
|
||||||
|
else:
|
||||||
|
logger.error(f"Не удалось переиндексировать документ {doc_id}, chunk_count=0")
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception(f"Ошибка переиндексации документа {doc_id}: {e}")
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
# Получение списков документов (используют методы db с фильтром indexed=TRUE)
|
# Получение списков документов (используют методы db с фильтром indexed=TRUE)
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user