PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Chaînes UTF-8 similaires pour le champ de saisie semi-automatique

Vous n'utilisez pas la classe d'opérateur fournie par le pg_trgm module. Je créerais un index comme celui-ci :

CREATE INDEX label_Lower_unaccent_trgm_idx
ON test_trgm USING gist (lower(unaccent_text(label)) gist_trgm_ops);

À l'origine, j'avais un index GIN ici, mais j'ai appris plus tard qu'un GiST est probablement encore mieux adapté à ce type de requête car il peut renvoyer des valeurs triées par similarité. Plus de détails :

  • Postgresql :faire correspondre des modèles entre deux colonnes
  • Trouver rapidement des chaînes similaires avec PostgreSQL

Votre requête doit correspondre à l'expression d'index pour pouvoir l'utiliser.

SELECT label
FROM   the_table
WHERE  lower(unaccent_text(label)) % 'fil'
ORDER  BY similarity(label, 'fil') DESC -- it's ok to use original string here

Cependant, "filbert" et "filé powder" ne sont en fait pas très similaires à "fil" selon l'opérateur %. Je soupçonne que ce que vous voulez vraiment, c'est ceci :

SELECT label
FROM   the_table
WHERE  lower(unaccent_text(label)) ~~ '%fil%'
ORDER  BY similarity(label, 'fil') DESC -- it's ok to use original string here

Cela trouvera toutes les chaînes contenant la chaîne de recherche et triera les meilleures correspondances en fonction du % l'opérateur en premier.

Et la partie juteuse :l'expression peut utiliser un index GIN ou GiST depuis PostgreSQL 9.1 ! Je cite le manuel sur le moule pg_trgm :

Depuis PostgreSQL 9.1, ces types d'index prennent également en charge les recherches d'index pour LIKE et ILIKE, par exemple

Si vous vouliez réellement utiliser le % opérateur :

Avez-vous essayé d'abaisser le seuil pour l'opérateur de similarité % avec set_limit() :

SELECT set_limit(0.1);

ou même plus bas ? La valeur par défaut est 0,3. Juste pour voir si c'est le seuil qui filtre les correspondances supplémentaires.