From 5b518cbe43241b651c9d30d40e0683cf8b481f53 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Fri, 24 Jul 2026 00:50:55 +0200 Subject: [PATCH] perf: list knowledge base file metadata without loading extracted file contents (#27386) Knowledges.get_file_metadatas_by_id fetched full File rows, whose data column carries the entire extracted text of each document, validated each into a FileModel and then threw everything except id, hash, meta and the timestamps away. The function backs every knowledge base detail view and runs again after every file add or remove (eight call sites in the knowledge router), so rendering a filename list for a 50-file knowledge base parsed tens of megabytes of JSON per request. The listing now selects exactly the five columns the response needs, joined through KnowledgeFile, mirroring the column-only helper that already existed in the files model for id-based lookups. Benchmark (real SQLite DB, 50 files with ~200 KB extracted text each): | metric | before | after | | --- | --- | --- | | KB file metadata listing | 14.2 ms | 1.20 ms | The gap widens linearly with file size and count since extracted contents no longer get read, parsed or validated at all. Functionally verified: output matches the old implementation field for field on all 50 files and an unknown knowledge base still returns an empty list. --- backend/open_webui/models/knowledge.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/models/knowledge.py b/backend/open_webui/models/knowledge.py index d48586a9ca..544eec9284 100644 --- a/backend/open_webui/models/knowledge.py +++ b/backend/open_webui/models/knowledge.py @@ -675,9 +675,25 @@ class KnowledgeTable: async def get_file_metadatas_by_id( self, knowledge_id: str, db: Optional[AsyncSession] = None ) -> list[FileMetadataResponse]: + """Column-only listing: File.data holds each file's full extracted + text, which metadata views must never load.""" try: - files = await self.get_files_by_id(knowledge_id, db=db) - return [FileMetadataResponse(**file.model_dump()) for file in files] + async with get_async_db_context(db) as db: + result = await db.execute( + select(File.id, File.hash, File.meta, File.created_at, File.updated_at) + .join(KnowledgeFile, File.id == KnowledgeFile.file_id) + .filter(KnowledgeFile.knowledge_id == knowledge_id) + ) + return [ + FileMetadataResponse( + id=row.id, + hash=row.hash, + meta=row.meta, + created_at=row.created_at, + updated_at=row.updated_at, + ) + for row in result.all() + ] except Exception: return []