mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2025-01-04 22:38:43 +00:00
Updates first_search_result functionality
This commit is contained in:
parent
76ab5a763c
commit
fbe05623ff
2 changed files with 24 additions and 9 deletions
|
@ -11,16 +11,18 @@ from bookwyrm.settings import MEDIA_FULL_URL
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=arguments-differ
|
# pylint: disable=arguments-differ
|
||||||
def search(query, min_confidence=0, filters=None):
|
def search(query, min_confidence=0, filters=None, return_first=False):
|
||||||
"""search your local database"""
|
"""search your local database"""
|
||||||
filters = filters or []
|
filters = filters or []
|
||||||
if not query:
|
if not query:
|
||||||
return []
|
return []
|
||||||
# first, try searching unqiue identifiers
|
# first, try searching unqiue identifiers
|
||||||
results = search_identifiers(query, *filters)
|
results = search_identifiers(query, *filters, return_first=return_first)
|
||||||
if not results:
|
if not results:
|
||||||
# then try searching title/author
|
# then try searching title/author
|
||||||
results = search_title_author(query, min_confidence, *filters)
|
results = search_title_author(
|
||||||
|
query, min_confidence, *filters, return_first=return_first
|
||||||
|
)
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,7 +70,7 @@ def format_search_result(search_result):
|
||||||
).json()
|
).json()
|
||||||
|
|
||||||
|
|
||||||
def search_identifiers(query, *filters):
|
def search_identifiers(query, *filters, return_first=False):
|
||||||
"""tries remote_id, isbn; defined as dedupe fields on the model"""
|
"""tries remote_id, isbn; defined as dedupe fields on the model"""
|
||||||
# pylint: disable=W0212
|
# pylint: disable=W0212
|
||||||
or_filters = [
|
or_filters = [
|
||||||
|
@ -87,15 +89,18 @@ def search_identifiers(query, *filters):
|
||||||
default_editions = models.Edition.objects.filter(
|
default_editions = models.Edition.objects.filter(
|
||||||
parent_work=OuterRef("parent_work")
|
parent_work=OuterRef("parent_work")
|
||||||
).order_by("-edition_rank")
|
).order_by("-edition_rank")
|
||||||
return (
|
results = (
|
||||||
results.annotate(default_id=Subquery(default_editions.values("id")[:1])).filter(
|
results.annotate(default_id=Subquery(default_editions.values("id")[:1])).filter(
|
||||||
default_id=F("id")
|
default_id=F("id")
|
||||||
)
|
)
|
||||||
or results
|
or results
|
||||||
)
|
)
|
||||||
|
if return_first:
|
||||||
|
return results.first()
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
def search_title_author(query, min_confidence, *filters):
|
def search_title_author(query, min_confidence, *filters, return_first=False):
|
||||||
"""searches for title and author"""
|
"""searches for title and author"""
|
||||||
query = SearchQuery(query, config="simple") | SearchQuery(query, config="english")
|
query = SearchQuery(query, config="simple") | SearchQuery(query, config="english")
|
||||||
results = (
|
results = (
|
||||||
|
@ -109,12 +114,17 @@ def search_title_author(query, min_confidence, *filters):
|
||||||
editions_of_work = results.values("parent_work__id").values_list("parent_work__id")
|
editions_of_work = results.values("parent_work__id").values_list("parent_work__id")
|
||||||
|
|
||||||
# filter out multiple editions of the same work
|
# filter out multiple editions of the same work
|
||||||
|
results = []
|
||||||
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()
|
||||||
default_rank = default.rank if default else 0
|
default_rank = default.rank if default else 0
|
||||||
# if mutliple books have the top rank, pick the default edition
|
# if mutliple books have the top rank, pick the default edition
|
||||||
if default_rank == editions.first().rank:
|
if default_rank == editions.first().rank:
|
||||||
yield default
|
result = default
|
||||||
else:
|
else:
|
||||||
yield editions.first()
|
result = editions.first()
|
||||||
|
if return_first:
|
||||||
|
return result
|
||||||
|
results.append(result)
|
||||||
|
return results
|
||||||
|
|
|
@ -10,7 +10,7 @@ from django.db.models import signals
|
||||||
|
|
||||||
from requests import HTTPError
|
from requests import HTTPError
|
||||||
|
|
||||||
from bookwyrm import models
|
from bookwyrm import book_search, models
|
||||||
from bookwyrm.tasks import app
|
from bookwyrm.tasks import app
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
@ -73,6 +73,11 @@ def search(query, min_confidence=0.1, return_first=False):
|
||||||
|
|
||||||
def first_search_result(query, min_confidence=0.1):
|
def first_search_result(query, min_confidence=0.1):
|
||||||
"""search until you find a result that fits"""
|
"""search until you find a result that fits"""
|
||||||
|
# try local search first
|
||||||
|
result = book_search.search(query, min_confidence=min_confidence, return_first=True)
|
||||||
|
if result:
|
||||||
|
return result
|
||||||
|
# otherwise, try remote endpoints
|
||||||
return search(query, min_confidence=min_confidence, return_first=True) or None
|
return search(query, min_confidence=min_confidence, return_first=True) or None
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue