Documentation PostgreSQL 14.22 » Langage SQL » Recherche plein texte » Dictionnaires

Précédent | Niveau supérieur | Suivant
12.5. Analyseurs | Sommaire | 12.7. Exemple de configuration

## 12.6. Dictionnaires

Les dictionnaires sont utilisés pour éliminer des mots qui ne devraient pas être considérés dans une recherche (termes courants), et pour normaliser des mots pour que des formes dérivées de ce même mot établissent une correspondance. Un mot normalisé avec succès est appelé un lexème. En dehors du fait d'améliorer la qualité de la recherche, la normalisation et la suppression des termes courants réduisent la taille de la représentation d'un document en `tsvector`, et donc améliorent les performances. La normalisation n'a pas toujours une signification linguistique et dépend habituellement de la sémantique de l'application.

Quelques exemples de normalisation :

- Linguistique -- les dictionnaires ispell tentent de réduire les mots en entrée en une forme normalisée ; les dictionnaires stemmer suppriment la fin des mots

- Les URL peuvent être réduites pour établir certaines correspondances :

  - http://www.pgsql.ru/db/mw/index.html

  - http://www.pgsql.ru/db/mw/

  - http://www.pgsql.ru/db/../db/mw/index.html

- Les noms de couleur peuvent être remplacés par leur valeur hexadécimale, par exemple `red, green, blue, magenta -> FF0000, 00FF00, 0000FF, FF00FF`

- En cas d'indexation de nombre, nous pouvons supprimer certains chiffres à fraction pour réduire les nombres possibles, donc par exemple 3.14159265359, 3.1415926, 3.14 seront identiques après normalisation si seuls deux chiffres sont conservés après le point décimal.

Un dictionnaire est un programme qui accepte un jeton en entrée et renvoie :

- un tableau de lexèmes si le jeton en entrée est connu dans le dictionnaire (notez qu'un jeton peut produire plusieurs lexèmes)

- un unique lexème avec le drapeau `TSL_FILTER` configuré, pour remplacer le jeton original avec un nouveau jeton à passer aux dictionnaires suivants (un dictionnaire de ce type est appelé un dictionnaire filtrant)

- un tableau vide si le dictionnaire connaît le jeton, mais que ce dernier est un terme courant

- `NULL` si le dictionnaire n'a pas reconnu le jeton en entrée

PostgreSQL fournit des dictionnaires prédéfinis pour de nombreuses langues. Il existe aussi plusieurs modèles prédéfinis qui peuvent être utilisés pour créer de nouveaux dictionnaires avec des paramètres personnalisés. Chaque modèle prédéfini de dictionnaire est décrit ci-dessous. Si aucun modèle ne convient, il est possible d'en créer de nouveaux ; voir le répertoire `contrib/` de PostgreSQL pour des exemples.

Une configuration de recherche plein texte lie un analyseur avec un ensemble de dictionnaires pour traiter les jetons en sortie de l'analyseur. Pour chaque type de jeton que l'analyseur peut renvoyer, une liste séparée de dictionnaires est indiquée par la configuration. Quand un jeton de ce type est trouvé par l'analyseur, chaque dictionnaire de la liste est consulté jusqu'à ce qu'un dictionnaire le reconnaisse comme un mot connu. S'il est identifié comme un terme courant ou si aucun dictionnaire ne le reconnaît, il sera ignoré et non indexé. Normalement, le premier dictionnaire qui renvoie une sortie non `NULL` détermine le résultat et tout dictionnaire restant n'est pas consulté ; par contre, un dictionnaire filtrant peut remplacer le mot donné avec un autre mot qui est ensuite passé aux dictionnaires suivants.

La règle générale pour la configuration de la liste des dictionnaires est de placer en premier les dictionnaires les plus précis, les plus spécifiques, puis les dictionnaires généralistes, en finissant avec un dictionnaire le plus général possible, comme un stemmer Snowball ou `simple`, qui reconnaît tout. Par exemple, pour une recherche en astronomie (configuration `astro_en`), vous pouvez lier le type de jeton `asciiword` (mot ASCII) vers un dictionnaire des synonymes des termes de l'astronomie, un dictionnaire anglais généraliste et un stemmer Snowball anglais :

    ALTER TEXT SEARCH CONFIGURATION astro_en
        ADD MAPPING FOR asciiword WITH astrosyn, english_ispell, english_stem;

Un dictionnaire filtrant peut être placé n'importe où dans la liste. Cependant, le placer à la fin n'a aucun intérêt. Les dictionnaires filtrants sont utiles pour normaliser partiellement les mots, ce qui permet de simplifier la tâche aux dictionnaires suivants. Par exemple, un dictionnaire filtrant peut être utilisé pour supprimer les accents des lettres accentuées. C'est ce que fait le module unaccent.

### 12.6.1. Termes courants

Les termes courants sont des mots très courants, apparaissant dans pratiquement chaque document et n'ont donc pas de valeur discriminatoire. Du coup, ils peuvent être ignorés dans le contexte de la recherche plein texte. Par exemple, tous les textes anglais contiennent des mots comme `a` et `the`, donc il est inutile de les stocker dans un index. Néanmoins, les termes courants n'affectent pas les positions dans `tsvector`, ce qui affecte le score :

    SELECT to_tsvector('english', 'in the list of stop words');
            to_tsvector
    ----------------------------
     'list':3 'stop':5 'word':6

Les positions 1, 2, 4 manquantes sont dues aux termes courants. Les scores calculés pour les documents avec et sans termes courants sont vraiment différents :

    SELECT ts_rank_cd (to_tsvector('english', 'in the list of stop words'), to_tsquery('list & stop'));
     ts_rank_cd
    ------------
           0.05

    SELECT ts_rank_cd (to_tsvector('english', 'list stop words'), to_tsquery('list & stop'));
     ts_rank_cd
    ------------
            0.1

C'est au dictionnaire de savoir comment traiter les mots courants. Par exemple, les dictionnaires `Ispell` normalisent tout d'abord les mots puis cherchent les termes courants alors que les stemmers `Snowball` vérifient d'abord leur liste de termes courants. La raison de leur comportement différent est qu'ils tentent de réduire le bruit.

### 12.6.2. Dictionnaire simple

Le modèle du dictionnaire `simple` opère en convertissant le jeton en entrée en minuscules puis en vérifiant s'il fait partie de la liste des mots courants qu'il a sur fichier. S'il est trouvé dans ce fichier, un tableau vide est renvoyé. Le jeton sera alors ignoré. Dans le cas contraire, la forme minuscule du mot est renvoyée en tant que lexème normalisé. Autrement, le dictionnaire peut être configuré pour rapporter les termes courants comme étant non reconnus, ce qui permet de les passer au prochain dictionnaire de la liste.

Voici un exemple d'une définition de dictionnaire utilisant le modèle `simple` :

    CREATE TEXT SEARCH DICTIONARY public.simple_dict (
        TEMPLATE = pg_catalog.simple,
        STOPWORDS = english
    );

Dans ce cas, `english` est le nom de base du fichier contenant les termes courants. Le nom complet du fichier sera donc `$SHAREDIR/tsearch_data/english.stop`, où `$SHAREDIR` est le répertoire des données partagées de l'installation de PostgreSQL (souvent `/usr/local/share/postgresql`, mais utilisez `pg_config --sharedir` pour vous en assurer). Le format du fichier est une simple liste de mots, un mot par ligne. Les lignes vides et les espaces en fin de mot sont ignorées. Les mots en majuscules sont basculés en minuscules, mais aucun autre traitement n'est réalisé sur le contenu de ce fichier.

Maintenant, nous pouvons tester notre dictionnaire :

    SELECT ts_lexize('public.simple_dict', 'YeS');
     ts_lexize
    -----------
     {yes}

    SELECT ts_lexize('public.simple_dict', 'The');
     ts_lexize
    -----------
     {}

Nous pouvons aussi choisir de renvoyer `NULL` à la place du mot en minuscules s'il n'est pas trouvé dans le fichier des termes courants. Ce comportement est sélectionné en configurant le paramètre `Accept` du dictionnaire à `false`. En continuant l'exemple :

    ALTER TEXT SEARCH DICTIONARY public.simple_dict ( Accept = false );

    SELECT ts_lexize('public.simple_dict', 'YeS');
     ts_lexize
    -----------

    SELECT ts_lexize('public.simple_dict', 'The');
     ts_lexize
    -----------
     {}

Avec le paramétrage par défaut d'`Accept` (à savoir, `true`), il est préférable de placer un dictionnaire `simple` à la fin de la liste des dictionnaires. `Accept` = `false` est seulement utile quand il y a au moins un dictionnaire après celui-ci.

### Attention

La plupart des types de dictionnaires se basent sur des fichiers de configuration, comme les fichiers de termes courants. Ces fichiers doivent être dans l'encodage UTF-8. Ils seront traduits vers l'encodage actuel de la base de données, s'il est différent, quand ils seront lus.

### Attention

Habituellement, une session lira un fichier de configuration du dictionnaire une seule fois, lors de la première utilisation. Si vous modifiez un fichier de configuration et que vous voulez forcer la prise en compte des modifications par les sessions en cours, exécutez une commande `ALTER TEXT SEARCH DICTIONARY` sur le dictionnaire. Cela peut être une mise à jour « à vide », donc sans réellement modifier des valeurs.

### 12.6.3. Dictionnaire des synonymes

Ce modèle de dictionnaire est utilisé pour créer des dictionnaires qui remplacent un mot par un synonyme. Les phrases ne sont pas supportées (utilisez le modèle thésaurus pour cela, Section 12.6.4). Un dictionnaire des synonymes peut être utilisé pour contourner des problèmes linguistiques, par exemple pour empêcher un dictionnaire stemmer anglais de réduire le mot « Paris » en « pari ». Il suffit d'avoir une ligne `Paris paris` dans le dictionnaire des synonymes et de le placer avant le dictionnaire `english_stem`. Par exemple :

    SELECT * FROM ts_debug('english', 'Paris');
       alias   |   description   | token |  dictionaries  |  dictionary  | lexemes
    -----------+-----------------+-------+----------------+--------------+---------
     asciiword | Word, all ASCII | Paris | {english_stem} | english_stem | {pari}

    CREATE TEXT SEARCH DICTIONARY my_synonym (
        TEMPLATE = synonym,
        SYNONYMS = my_synonyms
    );

    ALTER TEXT SEARCH CONFIGURATION english
        ALTER MAPPING FOR asciiword WITH my_synonym, english_stem;

    SELECT * FROM ts_debug('english', 'Paris');
       alias   |   description   | token |       dictionaries        | dictionary | lexemes
    -----------+-----------------+-------+---------------------------+------------+---------
     asciiword | Word, all ASCII | Paris | {my_synonym,english_stem} | my_synonym | {paris}

Le seul paramètre requis par le modèle `synonym` est `SYNONYMS`, qui est le nom de base de son fichier de configuration -- `my_synonyms` dans l'exemple ci-dessus. Le nom complet du fichier sera `$SHAREDIR/tsearch_data/my_synonyms.syn` (où `$SHAREDIR` correspond au répertoire des données partagées de l'installation de PostgreSQL). Le format du fichier est une ligne par mot à substituer, avec le mot suivi par son synonyme séparé par une espace blanche. Les lignes vierges et les espaces après les mots sont ignorées, les lettres majuscules sont mises en minuscules.

Le modèle `synonym` a aussi un paramètre optionnel, appelé `CaseSensitive`, qui vaut par défaut `false`. Quand `CaseSensitive` vaut `false`, les mots dans le fichier des synonymes sont mis en minuscules, comme les jetons en entrée. Quand il vaut vrai, les mots et les jetons ne sont plus mis en minuscules, mais comparés tels quels..

Un astérisque (`*`) peut être placé à la fin d'un synonyme dans le fichier de configuration. Ceci indique que le synonyme est un préfixe. L'astérisque est ignoré quand l'entrée est utilisée dans `to_tsvector()`, mais quand il est utilisé dans `to_tsquery()`, le résultat sera un élément de la requête avec le marqueur de correspondance du préfixe (voir Section 12.3.2). Par exemple, supposons que nous ayons ces entrées dans `$SHAREDIR/tsearch_data/synonym_sample.syn` :

    postgres        pgsql
    postgresql      pgsql
    postgre pgsql
    gogle   googl
    indices index*

Alors nous obtiendrons les résultats suivants :

    mydb=# CREATE TEXT SEARCH DICTIONARY syn (template=synonym, synonyms='synonym_sample');
    mydb=# SELECT ts_lexize('syn', 'indices');
     ts_lexize
    -----------
     {index}
    (1 row)

    mydb=# CREATE TEXT SEARCH CONFIGURATION tst (copy=simple);
    mydb=# ALTER TEXT SEARCH CONFIGURATION tst ALTER MAPPING FOR asciiword WITH syn;
    mydb=# SELECT to_tsvector('tst', 'indices');
     to_tsvector
    -------------
     'index':1
    (1 row)

    mydb=# SELECT to_tsquery('tst', 'indices');
     to_tsquery
    ------------
     'index':*
    (1 row)

    mydb=# SELECT 'indexes are very useful'::tsvector;
                tsvector
    ---------------------------------
     'are' 'indexes' 'useful' 'very'
    (1 row)

    mydb=# SELECT 'indexes are very useful'::tsvector @@ to_tsquery('tst', 'indices');
     ?column?
    ----------
     t
    (1 row)

### 12.6.4. Dictionnaire thésaurus

Un dictionnaire thésaurus (parfois abrégé en TZ) est un ensemble de mots qui incluent des informations sur les relations des mots et des phrases, par exemple des termes plus lointains (BT), plus proches (NT), des termes préférés, des termes non aimés, des termes en relation, etc.

De façon simple, un dictionnaire thésaurus remplace tous les termes par des termes préférés et, en option, conserve les termes originaux pour l'indexage. L'implémentation actuelle du dictionnaire thésaurus par PostgreSQL est une extension du dictionnaire des synonymes avec un support additionnel des phrases. Un dictionnaire thésaurus nécessite un fichier de configuration au format suivant :

    # ceci est un commentaire
    mots(s) : mot(s) indexé(s)
    d'autre(s) mot(s) : d'autre(s) mot(s) indexé(s)
    ...

où le deux-points (`:`) agit comme un délimiteur entre une phrase et son remplacement.

Un dictionnaire thésaurus utilise un sous-dictionnaire (qui est spécifié dans la configuration du dictionnaire) pour normaliser le texte en entrée avant la vérification des correspondances de phrases. Un seul sous-dictionnaire est sélectionnable. Une erreur est renvoyée si le sous-dictionnaire échoue dans la reconnaissance d'un mot. Dans ce cas, vous devez supprimer l'utilisation du mot ou le faire connaître au sous-dictionnaire. Vous pouvez placer un astérisque (`*`) devant un mot indexé pour ignorer l'utilisation du sous-dictionnaire, mais tous les mots doivent être connus du sous-dictionnaire.

Le dictionnaire thésaurus choisit la plus grande correspondance s'il existe plusieurs phrases correspondant à l'entrée.

Les mots spécifiques reconnus par le sous-dictionnaire ne peuvent pas être précisés ; à la place, utilisez `?` pour marquer tout emplacement où un terme courant peut apparaître. Par exemple, en supposant que `a` et `the` soient des termes courants d'après le sous-dictionnaire :

    ? one ? two : swsw

correspond à `a one the two` et à `the one a two`. Les deux pourraient être remplacés par `swsw`.

Comme un dictionnaire thésaurus a la possibilité de reconnaître des phrases, il doit se rappeler son état et interagir avec l'analyseur. Un dictionnaire thésaurus utilise ces assignations pour vérifier s'il doit gérer le mot suivant ou arrêter l'accumulation. Le dictionnaire thésaurus doit être configuré avec attention. Par exemple, si le dictionnaire thésaurus s'occupe seulement du type de jeton `asciiword`, alors une définition du dictionnaire thésaurus comme `one 7` ne fonctionnera pas, car le type de jeton `uint` n'est pas affecté au dictionnaire thésaurus.

### Attention

Les thésaurus sont utilisés lors des indexages pour que toute modification dans les paramètres du dictionnaire thésaurus nécessite un réindexage. Pour la plupart des autres types de dictionnaires, de petites modifications comme l'ajout ou la suppression de termes courants ne demandent pas un réindexage.

#### 12.6.4.1. Configuration du thésaurus

Pour définir un nouveau dictionnaire thésaurus, utilisez le modèle `thesaurus`. Par exemple :

    CREATE TEXT SEARCH DICTIONARY thesaurus_simple (
        TEMPLATE = thesaurus,
        DictFile = mythesaurus,
        Dictionary = pg_catalog.english_stem
    );

Dans ce cas :

- `thesaurus_simple` est le nom du nouveau dictionnaire

- `mythesaurus` est le nom de base du fichier de configuration du thésaurus. (Son nom complet est `$SHAREDIR/tsearch_data/mythesaurus.ths`, où `$SHAREDIR` est remplacé par le répertoire des données partagées de l'installation.)

- `pg_catalog.english_stem` est le sous-dictionnaire (ici un stemmer Snowball anglais) à utiliser pour la normalisation du thésaurus. Notez que le sous-dictionnaire aura sa propre configuration (par exemple, les termes courants) qui n'est pas affichée ici.

Maintenant, il est possible de lier le dictionnaire du thésaurus `thesaurus_simple` aux types de jetons désirés dans une configuration, par exemple :

    ALTER TEXT SEARCH CONFIGURATION russian
        ALTER MAPPING FOR asciiword, asciihword, hword_asciipart WITH thesaurus_simple;

#### 12.6.4.2. Exemple de thésaurus

Considérez un thésaurus d'astronomie `thesaurus_astro`, contenant quelques combinaisons de mots d'astronomie :

    supernovae stars : sn
    crab nebulae : crab

Ci-dessous, nous créons un dictionnaire et lions certains types de jetons à un thésaurus d'astronomie et à un stemmer anglais :

    CREATE TEXT SEARCH DICTIONARY thesaurus_astro (
        TEMPLATE = thesaurus,
        DictFile = thesaurus_astro,
        Dictionary = english_stem
    );

    ALTER TEXT SEARCH CONFIGURATION russian
        ALTER MAPPING FOR asciiword, asciihword, hword_asciipart WITH thesaurus_astro, english_stem;

Maintenant, nous pouvons voir comment cela fonctionne. `ts_lexize` n'est pas très utile pour tester un thésaurus, car elle traite l'entrée en tant que simple jeton. À la place, nous pouvons utiliser `plainto_tsquery` et `to_tsvector` qui cassera les chaînes en entrée en plusieurs jetons :

    SELECT plainto_tsquery('supernova star');
     plainto_tsquery
    -----------------
     'sn'

    SELECT to_tsvector('supernova star');
     to_tsvector
    -------------
     'sn':1

En principe, il est possible d'utiliser `to_tsquery` si vous placez l'argument entre guillemets :

    SELECT to_tsquery('''supernova star''');
     to_tsquery
    ------------
     'sn'

Notez que `supernova star` établit une correspondance avec `supernovae stars` dans `thesaurus_astro`, car nous avions indiqué le stemmer `english_stem` dans la définition du thésaurus. Le stemmer a supprimé `e` et `s`.

Pour indexer la phrase originale ainsi que son substitut, incluez-le dans la partie droite de la définition :

    supernovae stars : sn supernovae stars

    SELECT plainto_tsquery('supernova star');
           plainto_tsquery
    -----------------------------
     'sn' & 'supernova' & 'star'

### 12.6.5. Dictionnaire Ispell

Le modèle de dictionnaire Ispell ajoute le support des dictionnaires morphologiques qui peuvent normaliser plusieurs formes linguistiques différentes d'un mot en un même lexème. Par exemple, un dictionnaire Ispell anglais peut établir une correspondance avec toutes les déclinaisons et conjugaisons du terme `bank`, c'est-à-dire `banking`, `banked`, `banks`, `banks'` et `bank's`.

La distribution standard de PostgreSQL n'inclut aucun des fichiers de configuration Ispell. Les dictionnaires sont disponibles pour un grand nombre de langues à partir du site web Ispell. De plus, certains formats de fichiers dictionnaires plus modernes sont supportés -- MySpell (OO < 2.0.1) et Hunspell (OO >= 2.0.2). Une large liste de dictionnaires est disponible sur le Wiki d'OpenOffice .

Pour créer un dictionnaire Ispell, réalisez les étapes suivantes :

- télécharger les fichiers de configuration de dictionnaires. Ces fichiers OpenOffice portent l'extension `.oxt`. Il est nécessaire d'extraire les fichiers `.aff` et `.dic`, et de changer ces extensions en `.affix` et `.dict`. Pour certains fichiers de dictionnaire, il faut aussi convertir les caractères en encodage UTF-8 avec les commandes suivantes (par exemple, pour le dictionnaire du norvégien) :

      iconv -f ISO_8859-1 -t UTF-8 -o nn_no.affix nn_NO.aff
      iconv -f ISO_8859-1 -t UTF-8 -o nn_no.dict nn_NO.dic

- copier les fichiers dans le répertoire `$SHAREDIR/tsearch_data`

- charger les fichiers dans PostgreSQL avec la commande suivante :

      CREATE TEXT SEARCH DICTIONARY english_hunspell (
           TEMPLATE = ispell,
          DictFile = en_us,
          AffFile = en_us,
          Stopwords = english);

Ici, `DictFile`, `AffFile` et `StopWords` indiquent les noms de base des fichiers dictionnaire, affixes et termes courants. Le fichier des termes courants a le même format qu'indiqué ci-dessus pour le type de dictionnaire `simple`. Le format des autres fichiers n'est pas indiqué ici, mais est disponible sur les sites web mentionnés ci-dessus.

Les dictionnaires Ispell reconnaissent habituellement un ensemble limité de mots, pour qu'ils puissent être suivis par un dictionnaire encore plus généraliste ; par exemple un dictionnaire Snowball qui reconnaît tout.

Le fichier `.affix` de Ispell suit la structure suivante :

    prefixes
    flag *A:
        .           >   RE      # Comme dans enter > reenter
    suffixes
    flag T:
        E           >   ST      # Comme dans late > latest
        [^AEIOU]Y   >   -Y,IEST # Comme dans dirty > dirtiest
        [AEIOU]Y    >   EST     # Comme dans gray > grayest
        [^EY]       >   EST     # Comme dans small > smallest

Et le fichier `.dict` suit la structure suivante :

    lapse/ADGRS
    lard/DGRS
    large/PRTY
    lark/MRS

Le format du fichier `.dict` est :

    basic_form/affix_class_name

Dans le fichier `.affix`, chaque règle d'affixe est décrite dans le format suivant :

    condition > [-stripping_letters,] adding_affix

Ici, une condition a un format similaire au format des expressions régulières. Elle peut comporter des groupements `[...]` et `[^...]`. Par exemple, `[AEIOU]Y` signifie que la dernière lettre du mot est `"y"` et que l'avant-dernière lettre est `"a"`, `"e"`, `"i"`, `"o"` ou `"u"`. `[^EY]` signifie que la dernière lettre n'est ni `"e"` ni `"y"`.

Les dictionnaires Ispell supportent la séparation des mots composés, une fonctionnalité intéressante. Notez que le fichier d'affixes doit indiquer une option spéciale qui marque les mots du dictionnaire qui peuvent participer à une formation composée :

    compoundwords  controlled z

Voici quelques exemples en norvégien :

    SELECT ts_lexize('norwegian_ispell', 'overbuljongterningpakkmesterassistent');
       {over,buljong,terning,pakk,mester,assistent}
    SELECT ts_lexize('norwegian_ispell', 'sjokoladefabrikk');
       {sjokoladefabrikk,sjokolade,fabrikk}

Le format MySpell est un sous-ensemble du format Hunspell. Le fichier `.affix` de Hunspell suit la structure suivante :

    PFX A Y 1
    PFX A   0     re         .
    SFX T N 4
    SFX T   0     st         e
    SFX T   y     iest       [^aeiou]y
    SFX T   0     est        [aeiou]y
    SFX T   0     est        [^ey]

La première ligne d'une classe d'affixe est l'en-tête. Les champs des règles d'affixes sont listés après l'en-tête.

- nom du paramètre (PFX ou SFX)

- flag (nom de la classe d'affixe)

- éliminer les caractères au début (au préfixe) ou à la fin (au suffixe) du mot

- ajouter l'affixe

- condition ayant un format similaire à celui des expressions régulières.

Le fichier `.dict` ressemble au fichier `.dict` de Ispell :

    larder/M
    lardy/RT
    large/RSPMYT
    largehearted

### Note

MySpell ne supporte pas les mots composés. Hunspell a un support sophistiqué des mots composés. Actuellement, PostgreSQL implémente seulement les opérations basiques de Hunspell pour les mots composés.

### 12.6.6. Dictionnaire Snowball

Le modèle de dictionnaire Snowball est basé sur le projet de Martin Porter, inventeur du populaire algorithme stemming de Porter pour l'anglais. Snowball propose maintenant des algorithmes stemming pour un grand nombre de langues (voir le site Snowball pour plus d'informations). Chaque algorithme sait comment réduire les variantes standard d'un mot vers une base, ou stem, en rapport avec la langue. Un dictionnaire Snowball réclame un paramètre `langue` pour identifier le stemmer à utiliser et, en option, un nom de fichier des `termes courants` donnant une liste de mots à éliminer. (Les listes de termes courants au standard PostgreSQL sont aussi fournies par le projet Snowball.) Par exemple, il existe un équivalent de la définition interne en

    CREATE TEXT SEARCH DICTIONARY english_stem (
        TEMPLATE = snowball,
        Language = english,
        StopWords = english
    );

Le format du fichier des termes courants est identique à celui déjà expliqué.

Un dictionnaire Snowball reconnaît tout, qu'il soit ou non capable de simplifier le mot, donc il doit être placé en fin de la liste des dictionnaires. Il est inutile de l'avoir avant tout autre dictionnaire, car un jeton ne passera jamais au prochain dictionnaire.