-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GPS: Amélioration de l'autocomplete #5363
base: master
Are you sure you want to change the base?
Conversation
e689e49
to
49f0de1
Compare
🥁 La recette jetable est prête ! 👉 Je veux tester cette PR ! |
itou/www/autocomplete/views.py
Outdated
users = [ | ||
{ | ||
"text": user.get_full_name(), | ||
"text": f"{user.title}. {user.get_full_name()} ({user.jobseeker_profile.birthdate})", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On révèle maintenant encore plus d’informations avec ce endpoint, je ne sais pas si c’est OK point de vue juridique et sécu ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ce sont des infos auxquelles on a accès une fois la personne ajoutée, donc pour moi cela ne change pas (le endpoint a les même restrictions d'usage que la vu de détail)
EDIT: j'ajoute le titre qui n'est en fait pas dans la page suivante, mais on y trouve le NIR dont le premier chiffre donne la même info en général :)
Je ne suis pas trop fan des perfs, ça impacte le service des emplois en général. Serait-il possible pour le métier de trouver quelques critères plus discriminants ? Genre département, civilité 🤷 |
Hum... c'est vrai que c'est un problème... |
itou/www/autocomplete/views.py
Outdated
Exists( | ||
User.objects.filter(pk=OuterRef("pk")).filter( | ||
Q(first_name__unaccent__icontains=term) | Q(last_name__unaccent__icontains=term) | ||
), | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ça me semble bien violent avec autant de subqueries qu'il y a de termes 😱
Je pense qu'on doit pouvoir faire sans subqueries...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Si tu as une idée, je suis preneur !
Le truc c'est qu'afin de pouvoir mettre un score qui dépend du nombre de correspondances trouvées, ce sera forcément une subquery par terme, non ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def match_term(term):
return Cast(
- Exists(
- User.objects.filter(pk=OuterRef("pk")).filter(
- Q(first_name__unaccent__icontains=term) | Q(last_name__unaccent__icontains=term)
- ),
- ),
+ Q(first_name__unaccent__icontains=term) | Q(last_name__unaccent__icontains=term),
IntegerField(),
)
semble aussi bien marcher 😌
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Après ça reste violent vu que postgres est obligé de regarder et trier tous les comptes candidats...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Donc je pense que tu devrais également garder le filter(or_queries(name_q))
histoire que postgresql n'aie pas besoin systématiquement de traiter 1M+ de comptes à chaque requête 😬
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
C'est en effet beaucoup mieux, on passe de 3 à 2 secondes dans un cas de test, mais c'est pas suffisant pour le laisse en autocomplete dans cet état.
Le or_queries
n'améliore pas grand chose. Je pense que l'élément coûteux c'est de rechercher chaque terme dans prénom et nom. Donc le faire pour filter et compter, ou uniquement pour compter c'est kif-kif.
Par contre, en forçant la présence du premier terme, ça limite pas mal l'impact en performances quand il y a plusieurs termes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Et sinon, ts_vector de psql accepte un dictionnaire "simple" qui évite le stemming 🤩
Ce qui permet donc de laisser psql faire un truc plus optimisé niveau performances que ma première piste un peu à la mano
(voir la seconde PR )
b8b0713
to
4a76c83
Compare
4a76c83
to
e723ed3
Compare
Match every term against the full name, and order the results using the number of matched term. Using a manual match that allow to search with only part of the name (while full text search will only match full "words")
e723ed3
to
13658c1
Compare
🤔 Pourquoi ?
Les performances sont clairement inférieures, mais au moins le résultat est exploitable.
La version actuelle ne sera à rien sur des noms ou prénom trop communs (trop de résultats possibles pour être sur que la personne que l'on cherche apparaisse dans les 10 premiers)
On ajoute le titre si on le connaît, ainsi que la date de naissance pour mieux gérer les homonymes.
Niveau performances : ~ 1.25 secondes par requete (c'est donc super long)
Une alternative est présente ici :#5365 en utilisant la recherche plein texte
🍰 Comment ?
🚨 À vérifier
🏝️ Comment tester
💻 Captures d'écran