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.