Skip to content

Commit

Permalink
Fix order_by_relevance needed for Postgres and queryset ordered searc…
Browse files Browse the repository at this point in the history
…hes (#299)
  • Loading branch information
dopry committed Jan 17, 2023
1 parent d46c1b5 commit 11244d4
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 17 deletions.
21 changes: 12 additions & 9 deletions example/example/tests/test_grapple.py
Original file line number Diff line number Diff line change
Expand Up @@ -440,17 +440,17 @@ class PagesSearchTest(BaseGrappleTest):
def setUpTestData(cls):
cls.home = HomePage.objects.first()
BlogPageFactory(title="Alpha", parent=cls.home)
BlogPageFactory(title="Alpha Alpha", parent=cls.home)
BlogPageFactory(title="Gamma Beta", parent=cls.home)
BlogPageFactory(title="Alpha Beta", parent=cls.home)
BlogPageFactory(title="Beta Alpha", parent=cls.home)
BlogPageFactory(title="Alpha Gamma", parent=cls.home)
BlogPageFactory(title="Beta", parent=cls.home)
BlogPageFactory(title="Beta Alpha", parent=cls.home)
BlogPageFactory(title="Alpha Alpha", parent=cls.home)
BlogPageFactory(title="Gamma Gamma", parent=cls.home)
BlogPageFactory(title="Beta Beta", parent=cls.home)
BlogPageFactory(title="Beta Gamma", parent=cls.home)
BlogPageFactory(title="Gamma", parent=cls.home)
BlogPageFactory(title="Beta Gamma", parent=cls.home)
BlogPageFactory(title="Gamma Alpha", parent=cls.home)
BlogPageFactory(title="Gamma Beta", parent=cls.home)
BlogPageFactory(title="Gamma Gamma", parent=cls.home)

def test_natural_order(self):
query = """
Expand All @@ -460,15 +460,18 @@ def test_natural_order(self):
}
}
"""
"""
sqlite doesn't support scoring so natural order will be in the order of defintion.
with another database or elasticsearch backend the order will be different
"""
executed = self.client.execute(query, variables={"searchQuery": "Alpha"})
page_data = executed["data"].get("pages")

self.assertEquals(len(page_data), 6)
self.assertEquals(page_data[0]["title"], "Alpha")
self.assertEquals(page_data[1]["title"], "Alpha Alpha")
self.assertEquals(page_data[2]["title"], "Alpha Beta")
self.assertEquals(page_data[1]["title"], "Alpha Beta")
self.assertEquals(page_data[2]["title"], "Beta Alpha")
self.assertEquals(page_data[3]["title"], "Alpha Gamma")
self.assertEquals(page_data[4]["title"], "Beta Alpha")
self.assertEquals(page_data[4]["title"], "Alpha Alpha")
self.assertEquals(page_data[5]["title"], "Gamma Alpha")

def test_explicit_order(self):
Expand Down
19 changes: 11 additions & 8 deletions grapple/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

from django.conf import settings
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from wagtail.search.backends import get_search_backend
from wagtail.search.index import class_is_indexed
from wagtail.search.models import Query

Expand Down Expand Up @@ -103,8 +102,10 @@ def resolve_queryset(
else:
qs = qs.all()

order_by_relevance = True
if order is not None:
qs = qs.order_by(*(x.strip() for x in order.split(",")))
order_by_relevance = False

if collection is not None:
try:
Expand All @@ -123,7 +124,7 @@ def resolve_queryset(
query = Query.get(search_query)
query.add_hit()

qs = get_search_backend().search(search_query, qs)
qs = qs.search(search_query, order_by_relevance=order_by_relevance)

return _sliced_queryset(qs, limit, offset)

Expand Down Expand Up @@ -192,6 +193,13 @@ def resolve_paginated_queryset(
else:
qs = qs.all()

# order_by_relevance will always take precedence over an existing order_by in the Postgres backend
# we need to set it to False if we want to specify our own order_by.
order_by_relevance = True
if order is not None:
qs = qs.order_by(*(x.strip() for x in order.split(",")))
order_by_relevance = False

if id is None and search_query:
# Check if the queryset is searchable using Wagtail search.
if not class_is_indexed(qs.model):
Expand All @@ -201,12 +209,7 @@ def resolve_paginated_queryset(
query = Query.get(search_query)
query.add_hit()

results = get_search_backend().search(search_query, qs)

return get_paginated_result(results, page, per_page)

if order is not None:
qs = qs.order_by(*(x.strip() for x in order.split(",")))
qs = qs.search(search_query, order_by_relevance=order_by_relevance)

return get_paginated_result(qs, page, per_page)

Expand Down

0 comments on commit 11244d4

Please sign in to comment.