Skip to content

Commit 1d7a267

Browse files
committed
perf: optimize Library.search_tags
1 parent ea288e9 commit 1d7a267

File tree

1 file changed

+14
-29
lines changed

1 file changed

+14
-29
lines changed

src/tagstudio/core/library/alchemy/library.py

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@
7575
DB_VERSION_LEGACY_KEY,
7676
JSON_FILENAME,
7777
SQL_FILENAME,
78-
TAG_CHILDREN_QUERY,
7978
)
8079
from tagstudio.core.library.alchemy.db import make_tables
8180
from tagstudio.core.library.alchemy.enums import (
@@ -1071,13 +1070,10 @@ def search_library(
10711070
def search_tags(self, name: str | None, limit: int = 100) -> list[set[Tag]]:
10721071
"""Return a list of Tag records matching the query."""
10731072
with Session(self.engine) as session:
1074-
query = select(Tag).outerjoin(TagAlias).order_by(func.lower(Tag.name))
1075-
query = query.options(
1076-
selectinload(Tag.parent_tags),
1077-
selectinload(Tag.aliases),
1078-
)
1079-
if limit > 0:
1080-
query = query.limit(limit)
1073+
query = select(Tag.id, Tag.name).outerjoin(TagAlias)
1074+
1075+
if limit > 0 and (not name or len(name) == 1):
1076+
query = query.limit(limit).order_by(func.lower(Tag.name))
10811077

10821078
if name:
10831079
query = query.where(
@@ -1088,35 +1084,24 @@ def search_tags(self, name: str | None, limit: int = 100) -> list[set[Tag]]:
10881084
)
10891085
)
10901086

1091-
direct_tags = set(session.scalars(query))
1092-
ancestor_tag_ids: list[Tag] = []
1093-
for tag in direct_tags:
1094-
ancestor_tag_ids.extend(
1095-
list(session.scalars(TAG_CHILDREN_QUERY, {"tag_id": tag.id}))
1096-
)
1097-
1098-
ancestor_tags = session.scalars(
1099-
select(Tag)
1100-
.where(Tag.id.in_(ancestor_tag_ids))
1101-
.options(selectinload(Tag.parent_tags), selectinload(Tag.aliases))
1102-
)
1103-
1104-
res = [
1105-
direct_tags,
1106-
{at for at in ancestor_tags if at not in direct_tags},
1107-
]
1108-
1087+
tags = list(session.execute(query))
11091088
logger.info(
11101089
"searching tags",
11111090
search=name,
11121091
limit=limit,
11131092
statement=str(query),
1114-
results=len(res),
1093+
results=len(tags),
11151094
)
11161095

1117-
session.expunge_all()
1096+
tags.sort(key=lambda t: t[1].lower())
1097+
if limit <= 0:
1098+
limit = len(tags)
1099+
tag_ids = [t[0] for t in tags[:limit]]
11181100

1119-
return res
1101+
hierarchy = self.get_tag_hierarchy(tag_ids)
1102+
direct_tags = {hierarchy.pop(id) for id in tag_ids}
1103+
ancestor_tags = set(hierarchy.values())
1104+
return [direct_tags, ancestor_tags]
11201105

11211106
def update_entry_path(self, entry_id: int | Entry, path: Path) -> bool:
11221107
"""Set the path field of an entry.

0 commit comments

Comments
 (0)