Minor simplications to search queries

This commit is contained in:
Mouse Reeve 2021-06-17 14:46:58 -07:00
parent c16baea40d
commit 5d3639e47f

View file

@ -3,7 +3,7 @@ from functools import reduce
import operator import operator
from django.contrib.postgres.search import SearchRank, SearchVector from django.contrib.postgres.search import SearchRank, SearchVector
from django.db.models import Count, OuterRef, Subquery, F, Q from django.db.models import OuterRef, Subquery, F, Q
from bookwyrm import models from bookwyrm import models
from .abstract_connector import AbstractConnector, SearchResult from .abstract_connector import AbstractConnector, SearchResult
@ -122,6 +122,8 @@ def search_identifiers(query, *filters):
results = models.Edition.objects.filter( results = models.Edition.objects.filter(
*filters, reduce(operator.or_, (Q(**f) for f in or_filters)) *filters, reduce(operator.or_, (Q(**f) for f in or_filters))
).distinct() ).distinct()
if results.count() <= 1:
return results
# when there are multiple editions of the same work, pick the default. # when there are multiple editions of the same work, pick the default.
# it would be odd for this to happen. # it would be odd for this to happen.
@ -129,9 +131,8 @@ def search_identifiers(query, *filters):
parent_work=OuterRef("parent_work") parent_work=OuterRef("parent_work")
).order_by("-edition_rank") ).order_by("-edition_rank")
return ( return (
results.annotate(default_id=Subquery(default_editions.values("id")[:1])).filter( results.annotate(default_id=Subquery(default_editions.values("id")[:1]))
default_id=F("id") .filter(default_id=F("id"))
)
or results or results
) )
@ -146,7 +147,7 @@ def search_title_author(query, min_confidence, *filters):
) )
results = ( results = (
models.Edition.objects.annotate(search=vector) models.Edition.objects
.annotate(rank=SearchRank(vector, query)) .annotate(rank=SearchRank(vector, query))
.filter(*filters, rank__gt=min_confidence) .filter(*filters, rank__gt=min_confidence)
.order_by("-rank") .order_by("-rank")
@ -154,11 +155,11 @@ def search_title_author(query, min_confidence, *filters):
# when there are multiple editions of the same work, pick the closest # when there are multiple editions of the same work, pick the closest
editions_of_work = ( editions_of_work = (
results.values("parent_work") results.values("parent_work__id")
.annotate(Count("parent_work")) .values_list("parent_work__id")
.values_list("parent_work")
) )
# filter out multiple editions of the same work
for work_id in set(editions_of_work): for work_id in set(editions_of_work):
editions = results.filter(parent_work=work_id) editions = results.filter(parent_work=work_id)
default = editions.order_by("-edition_rank").first() default = editions.order_by("-edition_rank").first()