🔥(teams) remove all search by trigram
Remove trigram search for team access and contact
This commit is contained in:
@@ -8,6 +8,10 @@ and this project adheres to
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- 🔥(teams) remove search by trigram for team access and contact
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- ✨(domains) allow creation of "pending" mailboxes
|
- ✨(domains) allow creation of "pending" mailboxes
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
"""API endpoints"""
|
"""API endpoints"""
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.postgres.search import TrigramSimilarity
|
from django.db.models import OuterRef, Q, Subquery
|
||||||
from django.db.models import Func, Max, OuterRef, Q, Subquery, Value
|
|
||||||
from django.db.models.functions import Coalesce
|
|
||||||
|
|
||||||
from rest_framework import (
|
from rest_framework import (
|
||||||
decorators,
|
decorators,
|
||||||
@@ -157,19 +155,11 @@ class ContactViewSet(
|
|||||||
overriding_contacts__isnull=True,
|
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", ""):
|
if query := self.request.GET.get("q", ""):
|
||||||
query = Func(Value(query), function="unaccent")
|
queryset = queryset.filter(
|
||||||
similarity = TrigramSimilarity(
|
Q(full_name__unaccent__icontains=query)
|
||||||
Func("full_name", function="unaccent"),
|
| Q(short_name__unaccent__icontains=query)
|
||||||
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")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
serializer = self.get_serializer(queryset, many=True)
|
serializer = self.get_serializer(queryset, many=True)
|
||||||
@@ -349,20 +339,9 @@ class TeamAccessViewSet(
|
|||||||
|
|
||||||
if self.action in {"list", "retrieve"}:
|
if self.action in {"list", "retrieve"}:
|
||||||
if query := self.request.GET.get("q", ""):
|
if query := self.request.GET.get("q", ""):
|
||||||
similarity = Max(
|
queryset = queryset.filter(
|
||||||
TrigramSimilarity(
|
Q(user__email__unaccent__icontains=query)
|
||||||
Coalesce(Func("user__email", function="unaccent"), Value("")),
|
| Q(user__name__unaccent__icontains=query)
|
||||||
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")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Determine which role the logged-in user has in the team
|
# Determine which role the logged-in user has in the team
|
||||||
|
|||||||
@@ -131,19 +131,17 @@ def test_api_contacts_list_authenticated_by_full_name():
|
|||||||
contact_ids = [contact["id"] for contact in response.json()]
|
contact_ids = [contact["id"] for contact in response.json()]
|
||||||
assert contact_ids == [str(frank.id)]
|
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")
|
response = client.get("/api/v1.0/contacts/?q=ole")
|
||||||
|
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
contact_ids = [contact["id"] for contact in response.json()]
|
contact_ids = [contact["id"] for contact in response.json()]
|
||||||
# "Nicole Foole" matches twice on "ole"
|
assert contact_ids == [str(frank.id), str(nicole.id)]
|
||||||
assert contact_ids == [str(nicole.id), str(frank.id)]
|
|
||||||
|
|
||||||
response = client.get("/api/v1.0/contacts/?q=ool")
|
response = client.get("/api/v1.0/contacts/?q=ool")
|
||||||
|
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
contact_ids = [contact["id"] for contact in response.json()]
|
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():
|
def test_api_contacts_list_authenticated_uppercase_content():
|
||||||
|
|||||||
Reference in New Issue
Block a user