From a8e3d8d20e08ca9487928b0b7682791e40f495a9 Mon Sep 17 00:00:00 2001 From: Sabrina Demagny Date: Tue, 19 Nov 2024 22:58:10 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A5(teams)=20remove=20all=20search=20b?= =?UTF-8?q?y=20trigram?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove trigram search for team access and contact --- CHANGELOG.md | 4 +++ src/backend/core/api/viewsets.py | 37 +++++---------------- src/backend/core/tests/test_api_contacts.py | 6 ++-- 3 files changed, 14 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a794df..a92d035 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ and this project adheres to ## [Unreleased] +### Removed + +- 🔥(teams) remove search by trigram for team access and contact + ### Added - ✨(domains) allow creation of "pending" mailboxes diff --git a/src/backend/core/api/viewsets.py b/src/backend/core/api/viewsets.py index d45ecb9..7713cd8 100644 --- a/src/backend/core/api/viewsets.py +++ b/src/backend/core/api/viewsets.py @@ -1,9 +1,7 @@ """API endpoints""" from django.conf import settings -from django.contrib.postgres.search import TrigramSimilarity -from django.db.models import Func, Max, OuterRef, Q, Subquery, Value -from django.db.models.functions import Coalesce +from django.db.models import OuterRef, Q, Subquery from rest_framework import ( decorators, @@ -157,19 +155,11 @@ class ContactViewSet( overriding_contacts__isnull=True, ) - # Search by case-insensitive and accent-insensitive trigram similarity + # Search by case-insensitive and accent-insensitive similarity if query := self.request.GET.get("q", ""): - query = Func(Value(query), function="unaccent") - similarity = TrigramSimilarity( - Func("full_name", function="unaccent"), - query, - ) + TrigramSimilarity(Func("short_name", function="unaccent"), query) - queryset = ( - queryset.annotate(similarity=similarity) - .filter( - similarity__gte=0.05 - ) # Value determined by testing (test_api_contacts.py) - .order_by("-similarity") + queryset = queryset.filter( + Q(full_name__unaccent__icontains=query) + | Q(short_name__unaccent__icontains=query) ) serializer = self.get_serializer(queryset, many=True) @@ -349,20 +339,9 @@ class TeamAccessViewSet( if self.action in {"list", "retrieve"}: if query := self.request.GET.get("q", ""): - similarity = Max( - TrigramSimilarity( - Coalesce(Func("user__email", function="unaccent"), Value("")), - Func(Value(query), function="unaccent"), - ) - + TrigramSimilarity( - Coalesce(Func("user__name", function="unaccent"), Value("")), - Func(Value(query), function="unaccent"), - ) - ) - queryset = ( - queryset.annotate(similarity=similarity) - .filter(similarity__gte=SIMILARITY_THRESHOLD) - .order_by("-similarity") + queryset = queryset.filter( + Q(user__email__unaccent__icontains=query) + | Q(user__name__unaccent__icontains=query) ) # Determine which role the logged-in user has in the team diff --git a/src/backend/core/tests/test_api_contacts.py b/src/backend/core/tests/test_api_contacts.py index 5b73ec7..097166d 100644 --- a/src/backend/core/tests/test_api_contacts.py +++ b/src/backend/core/tests/test_api_contacts.py @@ -131,19 +131,17 @@ def test_api_contacts_list_authenticated_by_full_name(): contact_ids = [contact["id"] for contact in response.json()] assert contact_ids == [str(frank.id)] - # Result that matches a trigram twice ranks better than result that matches once response = client.get("/api/v1.0/contacts/?q=ole") assert response.status_code == 200 contact_ids = [contact["id"] for contact in response.json()] - # "Nicole Foole" matches twice on "ole" - assert contact_ids == [str(nicole.id), str(frank.id)] + assert contact_ids == [str(frank.id), str(nicole.id)] response = client.get("/api/v1.0/contacts/?q=ool") assert response.status_code == 200 contact_ids = [contact["id"] for contact in response.json()] - assert contact_ids == [str(nicole.id), str(frank.id)] + assert contact_ids == [str(frank.id), str(nicole.id)] def test_api_contacts_list_authenticated_uppercase_content():