Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
tonial committed Jan 10, 2025
1 parent 4d20221 commit 4a76c83
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Generated by Django 5.1.4 on 2025-01-10 10:22

import django.contrib.postgres.indexes
import django.contrib.postgres.lookups
import django.db.models.functions.text
from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
('cities', '0001_initial'),
('users', '0019_drop_jobseekerprofile_ata_allocation_since'),
]

operations = [
migrations.AddIndex(
model_name='user',
index=django.contrib.postgres.indexes.GinIndex(django.db.models.functions.text.Upper(django.contrib.postgres.lookups.Unaccent('first_name')), name='upper_unaccent_first_name_gin'),
),
migrations.AddIndex(
model_name='user',
index=django.contrib.postgres.indexes.GinIndex(django.db.models.functions.text.Upper(django.contrib.postgres.lookups.Unaccent('last_name')), name='upper_unaccent_last_name_gin'),
),
]
13 changes: 11 additions & 2 deletions itou/users/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
from citext import CIEmailField
from django.conf import settings
from django.contrib.auth.models import AbstractUser, UserManager
from django.contrib.postgres.indexes import OpClass
from django.contrib.postgres.indexes import GinIndex, OpClass
from django.contrib.postgres.lookups import Unaccent
from django.core.exceptions import ValidationError
from django.core.serializers.json import DjangoJSONEncoder
from django.core.validators import MaxLengthValidator, MinLengthValidator, RegexValidator
Expand Down Expand Up @@ -231,7 +232,15 @@ class Meta(AbstractUser.Meta):
models.Index(
OpClass(Upper("email"), name="text_pattern_ops"),
name="users_user_email_upper",
)
),
GinIndex(
Upper(Unaccent("first_name")),
name="upper_unaccent_first_name_gin",
),
GinIndex(
Upper(Unaccent("last_name")),
name="upper_unaccent_last_name_gin",
),
]
constraints = [
models.CheckConstraint(
Expand Down
23 changes: 21 additions & 2 deletions itou/www/autocomplete/views.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from datetime import datetime
from functools import reduce
from operator import add

from django.contrib.auth.decorators import login_not_required
from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector
from django.db.models import Exists, F, OuterRef, Q, Value
from django.db.models.functions import Least, Lower, NullIf, StrIndex
from django.db.models import Exists, F, IntegerField, OuterRef, Q, Value
from django.db.models.functions import Cast, Least, Lower, NullIf, StrIndex
from django.http import JsonResponse
from unidecode import unidecode

Expand Down Expand Up @@ -159,6 +161,23 @@ def gps_users_autocomplete(request):
)
).order_by("-rank")

# For documentation purpose : we can do it "manually"
# This allows us to type a part of the user name (LAUREN will match LAURENT)
# but it also mean that JEAN will match on users named JEANNE...
# The main issue it that it's 25% slower than with the full-text search

# def match_term(term):
# return Cast(
# Q(first_name__unaccent__icontains=term) | Q(last_name__unaccent__icontains=term),
# IntegerField(),
# )

# search_terms = [search_term for search_term in term.split(" ") if len(search_term) > 2]
# print(search_terms)
# users_qs = users_qs.annotate(
# rank=(reduce(add, [match_term(search_term) for search_term in search_terms]))
# ).order_by("-rank")

users = [
{
"text": f"{user.title}. {user.get_full_name()} ({user.jobseeker_profile.birthdate})",
Expand Down

0 comments on commit 4a76c83

Please sign in to comment.