This commit is contained in:
2026-05-11 15:23:34 +08:00
parent ed70a140a2
commit 547cbbb4a5
25 changed files with 721 additions and 332 deletions
@@ -7,6 +7,31 @@ use support\Db;
class ChunkSearchIndexRepository
{
public function countEmbeddedChunks(?string $archiveUid = null): int
{
$query = Db::table('chunks')
->where('embedding_status', EmbeddingStatus::EMBEDDED);
if ($archiveUid !== null && trim($archiveUid) !== '') {
$query->where('archive_uid', trim($archiveUid));
}
return (int) $query->count();
}
public function countIndexedChunks(?string $archiveUid = null): int
{
$query = Db::table('chunks')
->where('embedding_status', EmbeddingStatus::EMBEDDED)
->where('search_index_status', SearchIndexStatus::INDEXED);
if ($archiveUid !== null && trim($archiveUid) !== '') {
$query->where('archive_uid', trim($archiveUid));
}
return (int) $query->count();
}
public function resetEmbeddedChunksToPending(?string $archiveUid = null): int
{
$query = Db::table('chunks')
@@ -23,18 +48,44 @@ class ChunkSearchIndexRepository
]);
}
public function resetRecoverableChunksToPending(?string $archiveUid = null): int
{
$query = Db::table('chunks')
->where('embedding_status', EmbeddingStatus::EMBEDDED)
->whereIn('search_index_status', [
SearchIndexStatus::QUEUED,
SearchIndexStatus::INDEXING,
SearchIndexStatus::FAILED_RETRYABLE,
]);
if ($archiveUid !== null && trim($archiveUid) !== '') {
$query->where('archive_uid', trim($archiveUid));
}
return $query->update([
'search_index_status' => SearchIndexStatus::PENDING,
'search_index_error' => null,
'search_index_updated_at' => null,
]);
}
public function queuePendingArchiveTasks(int $limit): array
{
$statuses = [
SearchIndexStatus::PENDING,
SearchIndexStatus::QUEUED,
SearchIndexStatus::INDEXING,
SearchIndexStatus::FAILED_RETRYABLE,
];
$staleBefore = date('Y-m-d H:i:s', time() - max(60, (int) config('queue.tasks.stale_after_seconds', 900)));
$archiveUids = Db::table('chunks')
->where('embedding_status', EmbeddingStatus::EMBEDDED)
->whereIn('search_index_status', $statuses)
->where(function ($query) use ($staleBefore): void {
$query
->whereIn('search_index_status', [SearchIndexStatus::PENDING, SearchIndexStatus::FAILED_RETRYABLE])
->orWhere(function ($stale) use ($staleBefore): void {
$stale
->whereIn('search_index_status', [SearchIndexStatus::QUEUED, SearchIndexStatus::INDEXING])
->where(function ($time) use ($staleBefore): void {
$time->whereNull('search_index_updated_at')->orWhere('search_index_updated_at', '<', $staleBefore);
});
});
})
->select('archive_uid')
->groupBy('archive_uid')
->orderByRaw('MIN(id)')
@@ -47,7 +98,17 @@ class ChunkSearchIndexRepository
Db::table('chunks')
->where('archive_uid', $archiveUid)
->where('embedding_status', EmbeddingStatus::EMBEDDED)
->whereIn('search_index_status', $statuses)
->where(function ($query) use ($staleBefore): void {
$query
->whereIn('search_index_status', [SearchIndexStatus::PENDING, SearchIndexStatus::FAILED_RETRYABLE])
->orWhere(function ($stale) use ($staleBefore): void {
$stale
->whereIn('search_index_status', [SearchIndexStatus::QUEUED, SearchIndexStatus::INDEXING])
->where(function ($time) use ($staleBefore): void {
$time->whereNull('search_index_updated_at')->orWhere('search_index_updated_at', '<', $staleBefore);
});
});
})
->update([
'search_index_status' => SearchIndexStatus::QUEUED,
'search_index_error' => null,