fix employees search

This commit is contained in:
Kuroshini 2020-01-17 16:13:27 +03:00
parent a8ea238bfc
commit 8b4a6b0b74

View File

@ -11,12 +11,12 @@ from django.contrib.gis.db.models.functions import Distance
from django.contrib.gis.geos import Point
from django.contrib.gis.measure import Distance as DistanceMeasure
from django.contrib.postgres.fields import ArrayField
from django.contrib.postgres.search import TrigramDistance
from django.contrib.postgres.search import TrigramDistance, TrigramSimilarity
from django.contrib.postgres.indexes import GinIndex
from django.core.exceptions import ValidationError
from django.core.validators import MinValueValidator, MaxValueValidator
from django.db import models
from django.db.models import When, Case, F, ExpressionWrapper, Subquery, Q, Prefetch
from django.db.models import When, Case, F, ExpressionWrapper, Subquery, Q, Prefetch, Sum
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from phonenumber_field.modelfields import PhoneNumberField
@ -990,9 +990,37 @@ class EmployeeQuerySet(models.QuerySet):
def trigram_search(self, search_value: str):
"""Search with mistakes by name or last name."""
return self.annotate(
name_distance=TrigramDistance('name', search_value.lower()),
last_name_distance=TrigramDistance('last_name', search_value.lower()),
).filter(Q(name_distance__lte=0.7) | Q(last_name_distance__lte=0.7)).order_by('name_distance')
search_exact_match=models.Case(
models.When(Q(name__iexact=search_value) | Q(last_name__iexact=search_value),
then=100),
default=0,
output_field=models.FloatField()
),
search_contains_match=models.Case(
models.When(Q(name__icontains=search_value) | Q(last_name__icontains=search_value),
then=50),
default=0,
output_field=models.FloatField()
),
search_name_similarity=models.Case(
models.When(
Q(name__isnull=False),
then=TrigramSimilarity('name', search_value.lower())
),
default=0,
output_field=models.FloatField()
),
search_last_name_similarity=models.Case(
models.When(
Q(last_name__isnull=False),
then=TrigramSimilarity('last_name', search_value.lower())
),
default=0,
output_field=models.FloatField()
),
relevance=(F('search_name_similarity') + F('search_exact_match')
+ F('search_contains_match') + F('search_last_name_similarity'))
).filter(relevance__gte=0.3).order_by('-relevance')
def search_by_name_or_last_name(self, value):
"""Search by name or last_name."""