

Les exemples de la section précédente illustrent la correspondance plein texte en utilisant des chaînes simples. Cette section montre comment rechercher les données de la table, parfois en utilisant des index.
    Il est possible de faire des recherches plein texte sans index. Une requête
    qui ne fait qu'afficher le champ title de chaque
    ligne contenant le mot friend dans son champ
    body ressemble à ceci :
    
SELECT title
FROM pgweb
WHERE to_tsvector('english', body) @@ to_tsquery('english', 'friend');
    
    Cela trouve aussi les mots relatifs comme friends
    et friendly, car ils ont tous la même racine, le même
    lexème normalisé.
   
    La requête ci-dessus spécifie que la configuration
    english doit être utilisée pour analyser et normaliser
    les chaînes. Nous pouvons aussi omettre les paramètres de
    configuration :
    
SELECT title
FROM pgweb
WHERE to_tsvector(body) @@ to_tsquery('friend');
    Cette requête utilisera l'ensemble de configuration indiqué par default_text_search_config.
    Un exemple plus complexe est de sélectionner les dix documents les plus
    récents qui contiennent les mots create et
    table dans les champs title ou
    body :
    
SELECT title
FROM pgweb
WHERE to_tsvector(title || ' ' || body) @@ to_tsquery('create & table')
ORDER BY last_mod_date DESC LIMIT 10;
    
    Pour plus de clarté, nous omettons les appels à la fonction
    coalesce qui est nécessaire pour rechercher les lignes
    contenant NULL dans un des deux champs.
   
Bien que ces requêtes fonctionnent sans index, la plupart des applications trouvent cette approche trop lente, sauf peut-être pour des recherches occasionnelles. Une utilisation pratique de la recherche plein texte réclame habituellement la création d'un index.
Nous pouvons créer un index GIN (Section 12.9) pour accélérer les recherches plein texte :
CREATE INDEX pgweb_idx ON pgweb USING GIN(to_tsvector('english', body));
    
    Notez que la version à deux arguments de to_tsvector
    est utilisée. Seules les fonctions de recherche plein texte qui spécifient
    un nom de configuration peuvent être utilisées dans les index sur des
    expressions
    (Section 11.7). Ceci est dû au fait que le contenu
    de l'index ne doit pas être affecté par default_text_search_config. Dans le cas contraire, le
    contenu de l'index peut devenir incohérent parce que différentes entrées
    pourraient contenir des tsvector créés avec différentes
    configurations de recherche plein texte et qu'il ne serait plus possible de
    deviner à quelle configuration fait référence une entrée. Il serait
    impossible de sauvegarder et restaurer correctement un tel index.
   
    Comme la version à deux arguments de to_tsvector a
    été utilisée dans l'index ci-dessus, seule une référence de la requête
    qui utilise la version à deux arguments de to_tsvector
    avec le même nom de configuration utilise cet index. C'est-à-dire que
    WHERE to_tsvector('english', body) @@ 'a & b' peut
    utiliser l'index, mais WHERE to_tsvector(body) @@ 'a & b'
    ne le peut pas. Ceci nous assure qu'un index est seulement utilisé avec la
    même configuration que celle utilisée pour créer les entrées de l'index.
   
Il est possible de configurer des index avec des expressions plus complexes où le nom de la configuration est indiqué dans une autre colonne. Par exemple :
CREATE INDEX pgweb_idx ON pgweb USING GIN(to_tsvector(config_name, body));
    
    où config_name est une colonne de la table
    pgweb. Ceci permet l'utilisation de configurations
    mixtes dans le même index tout en enregistrant la configuration utilisée
    pour chaque entrée d'index. Ceci est utile dans le cas d'une bibliothèque
    de documents dans différentes langues. Encore une fois, les requêtes
    voulant utiliser l'index doivent être écrites pour correspondre à
    l'index, donc
    WHERE to_tsvector(config_name, body) @@ 'a & b'.
   
Les index peuvent même concaténer des colonnes :
CREATE INDEX pgweb_idx ON pgweb USING GIN(to_tsvector('english', title || ' ' || body));
    
    Une autre approche revient à créer une colonne tsvector
    séparée pour contenir le résultat de to_tsvector.
    Pour garder cette colonne automatiquement à jour par rapport à la source,
    on peut utiliser une colonne générée stockée. Cet
    exemple est une concaténation de title et
    body, en utilisant coalesce pour
    s'assurer qu'un champ est toujours indexé même si l'autre vaut
    NULL :
    
ALTER TABLE pgweb
    ADD COLUMN textsearchable_index_col tsvector
               GENERATED ALWAYS AS (to_tsvector('english', coalesce(title, '') || ' ' || coalesce(body, ''))) STORED;
    Puis nous créons un index GIN pour accélérer la recherche :
CREATE INDEX textsearch_idx ON pgweb USING GIN(textsearchable_index_col);
    Maintenant, nous sommes prêts pour des recherches plein texte rapides :
SELECT title
FROM pgweb
WHERE textsearchable_index_col @@ to_tsquery('create & table')
ORDER BY last_mod_date DESC
LIMIT 10;
    
    Un avantage de l'approche de la colonne séparée sur un index par
    expression est qu'il n'est pas nécessaire de spécifier explicitement la
    configuration de recherche plein texte dans les requêtes pour utiliser
    l'index. Comme indiqué dans l'exemple ci-dessus, la requête peut dépendre
    de default_text_search_config. Un autre avantage est que
    les recherches seront plus rapides, car il n'est plus nécessaire de refaire
    des appels à to_tsvector pour vérifier la
    correspondance de l'index. (Ceci est plus important lors de l'utilisation
    d'un index GiST par rapport à un index GIN ; voir la Section 12.9.)
    Néanmoins, l'approche de l'index par expression est plus simple à
    configurer et elle réclame moins d'espace disque, car la représentation
    tsvector n'est pas réellement stockée.