Toutes les requêtes doivent-elles être dans le dictionnaire?
Non. Parce que seuls les tiges de mots (selon la configuration de recherche de texte utilisée ) sont dans l'index pour commencer. Mais plus important:
Non . Parce que, en plus de cela, la recherche en texte intégral est également capable de faire correspondre les préfixes :
Cela fonctionnerait:
SELECT id, subject
FROM mailboxes
WHERE tsv @@ to_tsquery('simple', 'avail:*')
ORDER BY id DESC;
Notez 3 choses:
Utilisez to_tsquery()
, non plainto_tsquery()
, dans ce cas car (en citant le manuel ):
... plainto_tsquery
ne reconnaîtra pas les tsquery
opérateurs, les étiquettes de poids ou les étiquettes de correspondance de préfixe dans son entrée
Utilisez la 'simple'
configuration de recherche de texte pour générer le tsquery
puisque vous voulez évidemment prendre le mot «prévaloir» tel quel et ne pas appliquer le radical.
Ajouter :*
pour en faire une recherche de préfixe, c'est-à-dire trouver tous les lexèmes commençant par 'prévaloir'.
Important: Il s'agit d'une recherche de préfixe sur les lexèmes (tiges de mots) dans le document. Une correspondance d'expression régulière sans caractères génériques ( content ~* 'avail'
) n'est pas exactement la même! Ce dernier n'est pas ancré à gauche (au début des lexèmes) et trouverait également 'FOOavail' etc.
Il n'est pas clair si vous voulez le comportement décrit dans votre requête ou l'équivalent de l'expression régulière ajoutée. Les index de trigrammes ( pg_trgm
) comme @Evan déjà suggéré sont le bon outil pour cela. Il existe de nombreuses questions connexes sur dba.SE, essayez une recherche .
Aperçu:
Démo
SELECT *
FROM (
VALUES
('Zend has no framework')
, ('Zend Framework')
) sub(t), to_tsvector(t) AS tsv
WHERE tsv @@ to_tsquery('zend <-> fram:*');
id | t | tsv
----+----------------+------------------------
2 | Zend Framework | 'framework':2 'zend':1
Réponse connexe récente (chapitre Approche différente pour optimiser la recherche ):
Des courriels?
Puisque vous avez mentionné les e-mails, sachez que l'analyseur de recherche de texte identifie les e-mails et ne les divise pas en mots / lexèmes distincts. Considérer:
SELECT ts_debug('english', 'xangr@some.domain.com')
(email,"Email address",xangr@some.domain.com,{simple},simple,{xangr@some.domain.com})
Je remplacerais les séparateurs @
et .
dans vos courriels par un espace ( ' '
) pour indexer les mots contenus.
De plus, étant donné que vous traitez avec des noms dans des e-mails, pas avec des mots anglais (ou une autre langue) , j'utiliserais la 'simple'
configuration de recherche de texte pour désactiver le stemming et d'autres fonctionnalités linguistiques :
Construisez la ts_vector
colonne avec:
SELECT to_tsvector('simple', translate('joe.xangr@some.domain.com', '@.', ' ')) AS tsv;
:*
documenté, et 2) une mention pour construire ne devrait-elle pas aller deto_tsvector('simple'..)
pair avec des instructions selon lesquelles les requêtes futures de ce tsv nécessiteront également la configuration «simple» pour tsquery? Je pense que vous devriez clarifier les ramifications de la désactivation résultant d'un tsvector / tsquery.