Du bruger ikke den operatørklasse, der leveres af pg_trgm
modul. Jeg ville oprette et indeks som dette:
CREATE INDEX label_Lower_unaccent_trgm_idx ON test_trgm USING gist (lower(unaccent_text(label)) gist_trgm_ops);
Oprindeligt havde jeg et GIN-indeks her, men jeg lærte senere, at en GiST nok er endnu bedre egnet til denne form for forespørgsel, fordi den kan returnere værdier sorteret efter lighed. Flere detaljer:
- Postgresql:Matchende mønstre mellem to kolonner
- Hurtigt at finde lignende strenge med PostgreSQL
Din forespørgsel skal matche indeksudtrykket for at kunne gøre brug af det.
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
Men "filbert" og "filépulver" minder faktisk ikke meget om "fil" ifølge %-operatøren. Jeg formoder, at det du virkelig ønsker er dette:
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
Dette vil finde alle strenge, der indeholder søgestrengen, og sortere de bedste resultater i henhold til %
operatør først.
Og den saftige del:udtrykket kan bruge et GIN- eller GiST-indeks siden PostgreSQL 9.1 ! Jeg citerer manualen på pg_trgm moule:
Begyndende i PostgreSQL 9.1 understøtter disse indekstyper også indekssøgninger efter LIKE og ILIKE, for eksempel
Hvis du faktisk havde tænkt dig at bruge %
operatør:
Har du prøvet at sænke tærsklen for lighedsoperatoren %
med set_limit()
:
SELECT set_limit(0.1);
eller endnu lavere? Standard er 0,3. Bare for at se, om det er den tærskel, der filtrerer yderligere kampe.