perf: improve packages search-query

Improves performance for queries with large result sets.

The "group by" clause can be removed for all search types but the keywords.

Signed-off-by: moson-mo <mo-son@mailbox.org>
This commit is contained in:
moson-mo 2022-11-29 14:45:24 +01:00
parent d8e91d058c
commit 7a9448a3e5
No known key found for this signature in database
GPG key ID: 4A4760AB4EE15296
3 changed files with 33 additions and 17 deletions

View file

@ -136,7 +136,10 @@ class PackageSearch:
self._join_user() self._join_user()
self._join_keywords() self._join_keywords()
keywords = set(k.lower() for k in keywords) keywords = set(k.lower() for k in keywords)
self.query = self.query.filter(PackageKeyword.Keyword.in_(keywords)) self.query = self.query.filter(PackageKeyword.Keyword.in_(keywords)).group_by(
models.Package.Name
)
return self return self
def _search_by_maintainer(self, keywords: str) -> orm.Query: def _search_by_maintainer(self, keywords: str) -> orm.Query:

View file

@ -93,9 +93,7 @@ async def packages_get(
search.sort_by(sort_by, sort_order) search.sort_by(sort_by, sort_order)
# Insert search results into the context. # Insert search results into the context.
results = ( results = search.results().with_entities(
search.results()
.with_entities(
models.Package.ID, models.Package.ID,
models.Package.Name, models.Package.Name,
models.Package.PackageBaseID, models.Package.PackageBaseID,
@ -108,8 +106,6 @@ async def packages_get(
models.PackageVote.PackageBaseID.label("Voted"), models.PackageVote.PackageBaseID.label("Voted"),
models.PackageNotification.PackageBaseID.label("Notify"), models.PackageNotification.PackageBaseID.label("Notify"),
) )
.group_by(models.Package.Name)
)
packages = results.limit(per_page).offset(offset) packages = results.limit(per_page).offset(offset)
context["packages"] = packages context["packages"] = packages

View file

@ -740,6 +740,23 @@ def test_packages_search_by_keywords(client: TestClient, packages: list[Package]
rows = root.xpath('//table[@class="results"]/tbody/tr') rows = root.xpath('//table[@class="results"]/tbody/tr')
assert len(rows) == 1 assert len(rows) == 1
# Now let's add another keyword to the same package
with db.begin():
db.create(
PackageKeyword, PackageBase=package.PackageBase, Keyword="testKeyword2"
)
# And request packages with both keywords, we should still get 1 result.
with client as request:
response = request.get(
"/packages", params={"SeB": "k", "K": "testKeyword testKeyword2"}
)
assert response.status_code == int(HTTPStatus.OK)
root = parse_root(response.text)
rows = root.xpath('//table[@class="results"]/tbody/tr')
assert len(rows) == 1
def test_packages_search_by_maintainer( def test_packages_search_by_maintainer(
client: TestClient, maintainer: User, package: Package client: TestClient, maintainer: User, package: Package