Project

General

Profile

Development #42639

ajouter un index trigram sur CONCAT(first_name, ' ', last_name)

Added by Benjamin Dauvergne 2 months ago. Updated about 2 months ago.

Status:
Nouveau
Priority:
Normal
Assignee:
-
Category:
-
Target version:
-
Start date:
07 May 2020
Due date:
% Done:

0%

Patch proposed:
No
Planning:
No

Description

Le but serait de permettre une recherche approximative sur le nom via l'API (via un paramètre ?q=).

History

#2 Updated by Benjamin Dauvergne 2 months ago

  • Project changed from Nord - CD59 to Authentic 2

#3 Updated by Thomas Noël 2 months ago

Ne pourrait-on pas généraliser aux attributes avec searchable=True ?

#4 Updated by Benjamin Dauvergne 2 months ago

Les index trigram coûtent cher à maintenir, à chercher et les résultats sont complexes à trier donc je ne sais pas trop. L'autre problème c'est la recherche full-text sur trigram, ça n'existe pas vraiment il faut créer une formule pour décomposer le texte et dire dans quel champ on cherche, exemple sur zoo/nanterre initialement, si je recherche "Jean Marc Dupond 01/09/1975" :
  • déjà je sépare les mots de ce qui semble être une date, donc ["Jean", "Marc", "Dupond"] / datetime(1975, 9, 1)
  • ensuite je découpe la suite de mots en groupes que je match alternative sur le nom ou le prénom:
  • ou (prénom="jean" et nom="marc dupond") ou (nom="jean" et prénom="marc dupond")
    ou (prénom="jean marc" et nom="dupond") ou (nom="jean marc" et prénom="dupond")
    ou (nom="jean marc dupond")
  • ensuite pour chaque cas il faut donner un score et le combiner avec le score sur la date (la date c'est 0 ou 1 c'est assez simple), genre (score_prenom*score_nom) ** (2 - score_date) > 0.5

Très vite c'est devenu chiant de faire comme ça et au lieu d'avoir deux index trigrammes sur nom et prénom j'ai fait un index sur les deux concaténés CONCAT(prenoms || ' ' || nom) me donnant une seule clause 'jean marc dupond' ~ CONCAT(prenoms || ' ' || nom) beaucoup moins coûteuse pour postgres.

Si on commence à rajouter des champs autres ça devient impossible à gérer en mode "recherche full text" parce qu'on ne sait pas comment classer les résultats; si on peut rester sur nom/prénom/date de naissance c'est plus simple; et peut-être téléphone et email, l'important c'est qu'on arrive à extraire les éléments de la chaîne recherchée.

#5 Updated by Thomas Noël 2 months ago

Effectivement, je comprends la difficulté, ceci dit ça ne serait pas logique d'avoir un boolean "searchable" sur certains attributs et de ne plus le prendre en charge (on va vite aller vers des incompréhensions).

Avec un index trigramme limité à prénom et nom, une idée pourrait être que la recherche devienne un mix de cet index avec free_text_search ? Ceci étant je n'ai pas d'idée précise sur les pondérations/priorisations à faire... Et peut-être faudrait-il être un peu plus "rusé", ne chercher dans les mails que si un terme contient "@", dans les dates que si un terme contient un "/".

En tout cas, en dehors de ce travail à faire sur l'usager de l'index trigramme, je pense que sa création s'impose, et comme c'est l'objet de ce ticket, j'arrête de trop dériver ici ;)

#6 Updated by Benjamin Dauvergne 2 months ago

Thomas Noël a écrit :

Effectivement, je comprends la difficulté, ceci dit ça ne serait pas logique d'avoir un boolean "searchable" sur certains attributs et de ne plus le prendre en charge (on va vite aller vers des incompréhensions).

Avec un index trigramme limité à prénom et nom, une idée pourrait être que la recherche devienne un mix de cet index avec free_text_search ? Ceci étant je n'ai pas d'idée précise sur les pondérations/priorisations à faire... Et peut-être faudrait-il être un peu plus "rusé", ne chercher dans les mails que si un terme contient "@", dans les dates que si un terme contient un "/".

C'est exactement ce que je décris pour les mails et les dates mais peut-être mal.

Pour les autres champs on pourra chercher dedans les termes qui ne sont ni mails ni des dates comme on le fait maintenant, i.e. un terme à la fois mais c'est vrai que je serai plus à l'aise si on demandait un préfixe dans ce cas (comme sur le RSU on demande le préfixe '#' pour cherche dans les numéros de RSU ou le clé de fédération des logiciels métiers), genre pou champ 'rsa' contenant un identifiant de dossier RSA, taper « rsa:1234 ». Ce qui ne résout pas le problème de la pondération par rapport à la recherche approximative sachant que j'ai du mal à voir l'intérêt de combiner les deux en fait. Ça fait un joli exercice théorique mais ça n'a pas vraiment d'utilité (si tu as un identifiant unique style numéro de téléphone ou email, à la rigueur tu fais une typo et avoir une recherche approximative est intéressante, mais chercher avec plusieurs identifiants n'a pas forcément d'intérêt).

#7 Updated by Thomas Noël 2 months ago

En fait mon seul objectif ici est que le fait de cocher la case "Pris en compte dans les recherches :" (dans hobo, qui devient le searchable=True dans A2) garde sa fonction. Ce qui serait super c'est que la recherche trigram joue sur prénom et nom (avec plus d'intelligence que ce qu'on fait actuellement, donc). Et que pour les autres champs, on arrive à faire des recherches aussi. Et mixer les deux, quitte à décider que ce sont les prénom/nom qui gagnent.

Je ne sais pas si je suis assez clair. Peut-être qu'on dit la même chose :)

#8 Updated by Benjamin Dauvergne about 2 months ago

Thomas Noël a écrit :

En fait mon seul objectif ici est que le fait de cocher la case "Pris en compte dans les recherches :" (dans hobo, qui devient le searchable=True dans A2) garde sa fonction. Ce qui serait super c'est que la recherche trigram joue sur prénom et nom (avec plus d'intelligence que ce qu'on fait actuellement, donc). Et que pour les autres champs, on arrive à faire des recherches aussi. Et mixer les deux, quitte à décider que ce sont les prénom/nom qui gagnent.

Je ne sais pas si je suis assez clair. Peut-être qu'on dit la même chose :)

Nouveau plan :
  • plutôt que d'attribuer un comportement particulier à nom/prénom, construire un champ display_name comme dans w.c.s. à partir de nom/prénom (ce sera configurable comme w.c.s.) ce champ est particulier et indexé via trigram/unaccent/lower (zoo-like);
  • pour les tous les autres champs marqué "Pris en compte dans les recherches", créer une colonne fts comme dans w.c.s et l'alimenté, la recherche full text se fera dessus.

Also available in: Atom PDF