From 614f5b9246059c93917cd2c07190eb71820cc49a Mon Sep 17 00:00:00 2001 From: Darrel O'Pry Date: Mon, 16 Jan 2023 13:43:21 -0500 Subject: [PATCH] feat: add searchScore field to pages --- example/example/tests/test_grapple.py | 44 +++++++++++++++++++++++++-- grapple/types/pages.py | 9 ++++++ grapple/utils.py | 5 +++ 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/example/example/tests/test_grapple.py b/example/example/tests/test_grapple.py index 43a89f4e..c24eda78 100644 --- a/example/example/tests/test_grapple.py +++ b/example/example/tests/test_grapple.py @@ -1,6 +1,7 @@ import shutil import unittest from pydoc import locate +import unittest from unittest.mock import patch import wagtail_factories @@ -442,24 +443,61 @@ def setUpTestData(cls): connection.vendor != "sqlite", "sqlite doesn't support scoring so natural order will be in the order of defintion", ) - def test_natural_order_sqlite(self): + def test_searchQuery_order_by_relevance_sqlite(self): query = """ query($searchQuery: String, $order: String) { pages(searchQuery: $searchQuery, order: $order) { title + searchScore } } """ + 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[0]["searchScore"], None) self.assertEquals(page_data[1]["title"], "Alpha Alpha") + self.assertEquals(page_data[1]["searchScore"], None) self.assertEquals(page_data[2]["title"], "Alpha Beta") + self.assertEquals(page_data[2]["searchScore"], None) self.assertEquals(page_data[3]["title"], "Alpha Gamma") + self.assertEquals(page_data[3]["searchScore"], None) self.assertEquals(page_data[4]["title"], "Beta Alpha") + self.assertEquals(page_data[4]["searchScore"], None) self.assertEquals(page_data[5]["title"], "Gamma Alpha") + self.assertEquals(page_data[5]["searchScore"], None) + + @unittest.skipIf( + connection.vendor != "postgresql", + "postgres supports scoring so natural order will be in the order of score", + ) + def test_searchQuery_order_by_relevance_postgres(self): + query = """ + query($searchQuery: String, $order: String) { + pages(searchQuery: $searchQuery, order: $order) { + title + searchScore + } + } + """ + + 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 Alpha") + self.assertEquals(page_data[0]["searchScore"], 0.23700128495693207) + self.assertEquals(page_data[1]["title"], "Alpha") + self.assertEquals(page_data[1]["searchScore"], 0.18960101902484894) + self.assertEquals(page_data[2]["title"], "Gamma Alpha") + self.assertEquals(page_data[2]["searchScore"], 0.11060059443116188) + self.assertEquals(page_data[3]["title"], "Beta Alpha") + self.assertEquals(page_data[3]["searchScore"], 0.11060059443116188) + self.assertEquals(page_data[4]["title"], "Alpha Gamma") + self.assertEquals(page_data[4]["searchScore"], 0.11060059443116188) + self.assertEquals(page_data[5]["title"], "Alpha Beta") + self.assertEquals(page_data[5]["searchScore"], 0.10533389945824942) def test_explicit_order(self): query = """ @@ -476,9 +514,9 @@ def test_explicit_order(self): self.assertEquals(len(page_data), 6) self.assertEquals(page_data[0]["title"], "Gamma Gamma") - self.assertEquals(page_data[3]["title"], "Gamma") self.assertEquals(page_data[1]["title"], "Gamma Beta") self.assertEquals(page_data[2]["title"], "Gamma Alpha") + self.assertEquals(page_data[3]["title"], "Gamma") self.assertEquals(page_data[4]["title"], "Beta Gamma") self.assertEquals(page_data[5]["title"], "Alpha Gamma") diff --git a/grapple/types/pages.py b/grapple/types/pages.py index 171058d2..7f3c254a 100644 --- a/grapple/types/pages.py +++ b/grapple/types/pages.py @@ -56,6 +56,8 @@ class PageInterface(graphene.Interface): graphene.NonNull(lambda: PageInterface), enable_search=True, required=True ) + search_score = graphene.Float() + @classmethod def resolve_type(cls, instance, info, **kwargs): """ @@ -149,6 +151,13 @@ def resolve_seo_title(self, info, **kwargs): """ return self.seo_title or self.title + def resolve_search_score(self, info, **kwargs): + """ + Get page's search score, will be None if not in a search context. + """ + return getattr(self, "search_score", None) + + class Page(DjangoObjectType): """ diff --git a/grapple/utils.py b/grapple/utils.py index 51f8ef0b..db982e70 100644 --- a/grapple/utils.py +++ b/grapple/utils.py @@ -1,5 +1,6 @@ from django.conf import settings from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator +from django.db import connection from wagtail.models import Site from wagtail.search.index import class_is_indexed from wagtail.search.models import Query @@ -112,6 +113,8 @@ def resolve_queryset( query.add_hit() qs = qs.search(search_query, order_by_relevance=order_by_relevance) + if connection.vendor != 'sqlite': + qs = qs.annotate_score("search_score") return _sliced_queryset(qs, limit, offset) @@ -197,6 +200,8 @@ def resolve_paginated_queryset( query.add_hit() qs = qs.search(search_query, order_by_relevance=order_by_relevance) + if connection.vendor != 'sqlite': + qs = qs.annotate_score("search_score") return get_paginated_result(qs, page, per_page)