lakebase_tokenizer
L’extension lakebase_tokenizer ajoute une tokenisation configurable à la recherche en texte intégral PostgreSQL dans Lakebase, y compris le traitement des mots entiers et l’analyse morphologique pour le texte chinois, japonais et coréen (CJK). Les configurations de recherche en texte intégral créées avec l’extension fonctionnent avec to_tsvector, l’opérateur @@, les fonctions de classement et les index GIN. Vous pouvez également utiliser des valeurs tsvector générées avec lakebase_text pour le classement BM25.
L’extension fournit les Template tokenizer_wholeword et tokenizer_morph via l’interface de dictionnaire de recherche textuelle standard de PostgreSQL. Utilisez tokenizer_wholeword pour le traitement des mots entiers, y compris la normalisation, les mots vides, les synonymes et la radicalisation en anglais. Utilisez tokenizer_morph pour l’analyse morphologique du CJK.
Installer
Installez l'extension dans votre base de données. Les exemples de cette page utilisent un schéma dédié pour permettre d'identifier facilement les objets d'extension :
CREATE SCHEMA IF NOT EXISTS tokenizer_ext;
CREATE EXTENSION IF NOT EXISTS lakebase_tokenizer WITH SCHEMA tokenizer_ext;
L’extension est déplaçable. Vous pouvez remplacer tokenizer_ext par un autre schéma lorsque vous l’installez.
Mettre à jour l’extension
Une nouvelle version de Lakebase Search peut apporter de nouvelles fonctionnalités, des correctifs et des améliorations des performances. PostgreSQL ne met pas automatiquement à jour la version de l'extension installée. Vérifiez les versions installées et la dernière version disponible :
SELECT installed_version, default_version
FROM pg_available_extensions
WHERE name = 'lakebase_tokenizer';
Mettez à jour l’extension vers la dernière version disponible :
ALTER EXTENSION lakebase_tokenizer UPDATE;
ALTER EXTENSION ne régénère pas les valeurs tsvector stockées et ne reconstruit pas les index GIN ou lakebase_bm25 dépendants. Si une mise à jour modifie le résultat de la tokenisation, régénérez les valeurs tsvector stockées et suivez les notes de version pour toute maintenance d'index requise.
La mise à niveau de 0.1.x vers 0.2.0 ne modifie pas le résultat de la tokenisation. La version 0.2.0 ajoute le template tokenizer_morph et les configurations CJK intégrées, et laisse vos configurations existantes inchangées ; vous n’avez donc pas besoin de régénérer les valeurs tsvector ni de reconstruire les index.
Démarrage start
Choisissez un chemin en fonction du langage de votre texte :
- Pour l'anglais et d'autres langues délimitées par des espaces, créez un dictionnaire à partir du Template
tokenizer_wholeword. - Pour le texte chinois, japonais ou coréen, utilisez une configuration intégrée. Vous n'avez pas besoin de créer un dictionnaire.
Texte de mot entier
L’exemple suivant crée un dictionnaire à partir du template tokenizer_wholeword, puis y associe des types de token PostgreSQL courants dans une configuration de recherche textuelle :
CREATE TEXT SEARCH DICTIONARY documents_dict (
TEMPLATE = tokenizer_ext.tokenizer_wholeword,
Lowercase = 'true',
StripAccents = 'true',
Stemmer = 'english'
);
CREATE TEXT SEARCH CONFIGURATION documents_cfg (COPY = pg_catalog.simple);
ALTER TEXT SEARCH CONFIGURATION documents_cfg
ALTER MAPPING FOR asciiword, word, numword, hword_numpart, hword_part, hword_asciipart
WITH documents_dict;
Utilisez la configuration pour produire un tsvector, créez un index GIN et exécutez des requêtes en texte intégral :
CREATE TABLE documents (
id BIGSERIAL PRIMARY KEY,
body TEXT NOT NULL,
search_vector TSVECTOR GENERATED ALWAYS AS (
to_tsvector('documents_cfg', body)
) STORED
);
INSERT INTO documents (body) VALUES
('Cats are running near the café.'),
('A dog is sleeping in the house.');
CREATE INDEX documents_search_idx ON documents USING gin (search_vector);
SELECT id, body
FROM documents
WHERE search_vector @@ plainto_tsquery('documents_cfg', 'running café');
Utilisez la même configuration de recherche de texte pour les documents et les requêtes afin que les deux côtés appliquent la même stratégie de tokenisation et les mêmes options.
Texte CJK
L'installation de l'extension crée les configurations de recherche textuelle tokenizer_chinese, tokenizer_japanese et tokenizer_korean. Utilisez directement l'un d'entre eux pour produire un tsvector, créer un index GIN et exécuter des requêtes en texte intégral :
- Chinese
- Japanese
- Korean
CREATE TABLE chinese_documents (
id BIGSERIAL PRIMARY KEY,
body TEXT NOT NULL,
search_vector TSVECTOR GENERATED ALWAYS AS (
to_tsvector('tokenizer_ext.tokenizer_chinese', body)
) STORED
);
INSERT INTO chinese_documents (body) VALUES
('现代分布式文件系统架构');
CREATE INDEX chinese_idx ON chinese_documents USING gin (search_vector);
-- The built-in Chinese configuration uses mixed mode, so use plainto_tsquery instead of to_tsquery.
SELECT id, body
FROM chinese_documents
WHERE search_vector @@ plainto_tsquery('tokenizer_ext.tokenizer_chinese', '现代分布式');
CREATE TABLE japanese_documents (
id BIGSERIAL PRIMARY KEY,
body TEXT NOT NULL,
search_vector TSVECTOR GENERATED ALWAYS AS (
to_tsvector('tokenizer_ext.tokenizer_japanese', body)
) STORED
);
INSERT INTO japanese_documents (body) VALUES
('関西国際空港へのアクセス');
CREATE INDEX japanese_idx ON japanese_documents USING gin (search_vector);
SELECT id, body
FROM japanese_documents
WHERE search_vector @@ to_tsquery('tokenizer_ext.tokenizer_japanese', '関西国際空港');
CREATE TABLE korean_documents (
id BIGSERIAL PRIMARY KEY,
body TEXT NOT NULL,
search_vector TSVECTOR GENERATED ALWAYS AS (
to_tsvector('tokenizer_ext.tokenizer_korean', body)
) STORED
);
INSERT INTO korean_documents (body) VALUES
('선생님께서 도서관에 갑니다');
CREATE INDEX korean_idx ON korean_documents USING gin (search_vector);
SELECT id, body
FROM korean_documents
WHERE search_vector @@ to_tsquery('tokenizer_ext.tokenizer_korean', '선생님께서');
Template: tokenizer_wholeword
Comment ça marche
For each token passed to the dictionary by PostgreSQL's text-search parser, tokenizer_wholeword applies these Opérations:
Lowercase: convertir le jeton en minuscules.Normalize: appliquez la normalisation Unicode.StripAccents: Supprimer les accents.EnglishPossessive: supprimer un suffixe possessif anglais lorsqu'il reste au moins un caractère.Stopwords: N'émettez aucun lexème et arrêtez le traitement si le token correspond à un mot vide configuré. Le jeton est omis dutsvectorgénéré.Synonyms: émettre le remplacement configuré et arrêter le traitement si le token correspond à un synonyme.Stemmer: Si aucun synonyme ne correspond et que la recherche par radical est activée, appliquez le radicalisateur anglais.
Ajouter des mots vides et des synonymes
Le template tokenizer_wholeword peut charger des mots vides et des synonymes personnalisés à partir des tables SQL lakebase_tokenizer_stopwords et lakebase_tokenizer_synonyms gérées par l’extension. La colonne name regroupe les lignes en un ensemble que vous sélectionnez avec l’option de dictionnaire Stopwords ou Synonyms.
INSERT INTO tokenizer_ext.lakebase_tokenizer_stopwords (name, word) VALUES
('app_stopwords', 'the'),
('app_stopwords', 'and'),
('app_stopwords', 'or');
INSERT INTO tokenizer_ext.lakebase_tokenizer_synonyms (name, word, synonym) VALUES
('app_synonyms', 'usa', 'united_states'),
('app_synonyms', 'uk', 'united_kingdom');
Référencez les ensembles lorsque vous créez ou modifiez un dictionnaire tokenizer_wholeword :
ALTER TEXT SEARCH DICTIONARY documents_dict (
Stopwords = 'app_stopwords',
Synonyms = 'app_synonyms'
);
L'extension compare les mots vides et les mots sources de synonymes avec chaque jeton après avoir appliqué Lowercase, Normalize, StripAccents et EnglishPossessive, mais avant d'appliquer Stemmer. Les entrées de catalogue ne sont pas transformées automatiquement ; stockez-les donc sous la forme exacte produite par ces options activées :
- With
Lowercase = 'true', use lowercase entries. WithLowercase = 'false', capitalization must match the token. - Avec
Normalizeactivé, stockez les entrées dans la forme de normalisation Unicode sélectionnée. - Avec
StripAccents = 'true', stockez la forme sans accents. Par exemple, stockezcafepour correspondre àcafé. - Stockez la forme avant la stemming. Par exemple, avec
Stemmer = 'english', une entréerunne correspond pas àrunning. Ajoutezrunningpour filtrer ou remplacer ce jeton.
Les ensembles de noms peuvent contenir jusqu'à 256 octets. Les mots et les synonymes peuvent contenir jusqu'à 1 024 octets. Chaque ensemble de mots vides ou de synonymes nommé peut contenir jusqu'à 100 000 lignes.
Un remplacement de synonyme est émis exactement tel qu'il est stocké et n'est pas traité par le racineur (« stemmer »). Les synonymes prennent en charge un seul remplacement pour chaque mot source. Pour représenter un remplacement de plusieurs mots sous la forme d'un seul lexème, utilisez un séparateur tel qu'un trait de soulignement, comme dans united_states.
Après avoir modifié un ensemble, le propriétaire de chaque dictionnaire qui fait référence à l'ensemble doit exécuter un ALTER TEXT SEARCH DICTIONARY vide pour forcer un rechargement :
ALTER TEXT SEARCH DICTIONARY documents_dict (dummy);
L'option dummy n'existe pas sur tokenizer_wholeword. Omettre une valeur demande à PostgreSQL de supprimer cette option inexistante, ce qui invalide le cache sans modifier aucune des options configurées du dictionnaire.
Après le rechargement du dictionnaire, régénérez les valeurs tsvector stockées en réécrivant les lignes source :
UPDATE documents SET body = body;
Rôles et accès
Utiliser deux rôles pour séparer l'accès des applications de l'administration du tokenizer :
app_roleutilise les dictionnaires existants. Il lui fautUSAGEsur les schémas pertinents etSELECTsur les tables du catalogue d'extension, mais il n'a pas besoin d'être propriétaire des dictionnaires.tokenizer_admingère les ensembles de mots vides et de synonymes, crée et possède les dictionnaires et les configurations de recherche textuelle, et exécute la commande de rechargement après la modification d'un ensemble.
Accordez l'accès au schéma d'extension et aux tables du catalogue :
GRANT USAGE ON SCHEMA tokenizer_ext TO app_role, tokenizer_admin;
GRANT SELECT ON
tokenizer_ext.lakebase_tokenizer_stopwords,
tokenizer_ext.lakebase_tokenizer_synonyms
TO app_role;
GRANT SELECT, INSERT, UPDATE, DELETE ON
tokenizer_ext.lakebase_tokenizer_stopwords,
tokenizer_ext.lakebase_tokenizer_synonyms
TO tokenizer_admin;
tokenizer_admin nécessite également CREATE sur le schéma où les dictionnaires et les configurations de recherche textuelle sont stockés. Créez ces objets en tant que tokenizer_admin ou transférez-leur la propriété. L'accès en écriture aux tables du catalogue ne confère pas la propriété des dictionnaires existants.
Options
Spécifiez les options tokenizer_wholeword dans CREATE TEXT SEARCH DICTIONARY ou ALTER TEXT SEARCH DICTIONARY. Les noms d'option ne sont pas sensibles à la casse.
Option | Type | Par défaut | Description |
|---|---|---|---|
| booléen |
| Convertit les tokens en minuscules avant d'appliquer d'autres Opérations. |
|
|
| Applique la forme de normalisation Unicode sélectionnée. Cette opération normalise la représentation, mais ne supprime pas les caractères. Par exemple, |
| booléen |
| Supprime un suffixe final |
| booléen |
| S'applique à la normalisation NFKD et supprime les caractères diacritiques combinants. Par exemple, |
| définir le nom | Aucun | Utilise l'ensemble nommé de |
| définir le nom | Aucun | Utilise l’ensemble nommé de remplacements biunivoques de |
|
| Aucun | Utilise le bundle Snowball 3.1.0 Racineur anglais. Omettez cette option pour désactiver la racinisation. Le racineur n’inclut pas de liste de mots vides. |
Tables de catalogue
Table | Colonnes | Description |
|---|---|---|
|
| Stocke des ensembles de mots d'arrêt nommés pour |
|
| Stocke les remplacements un-à-un nommés pour |
Template: tokenizer_morph
Le template tokenizer_morph fournit la prise en charge de la tokenisation pour le texte chinois, japonais et coréen dans la recherche en texte intégral PostgreSQL. Utilisez une configuration de recherche de texte intégrée ou définissez-en une personnalisée pour contrôler la génération des termes.
Comment ça marche
tokenizer_morph utilise l'analyseur Lindera avec des dictionnaires regroupés : Jieba pour le chinois, IPADIC pour le japonais et MeCab KoDic pour le coréen.
Pour les jetons de l’analyseur coréen, tokenizer_morph remplace d’abord ㆍ (U+318D) par une limite de jeton.
Pour chaque jeton transmis au dictionnaire par l’analyseur de recherche textuelle de PostgreSQL, tokenizer_morph applique les opérations dans l’ordre :
Normalize: Appliquez la normalisation Unicode au token de l’analyseur.Language: Segmenter le jeton de l'analyseur avec l'analyseur de langue sélectionné.- Filtre de symboles : Supprime les segments qui ne contiennent aucune lettre ou chiffre.
- Analyse spécifique à la langue : transformez chaque segment restant en zéro ou plusieurs termes, comme décrit ci-dessous.
Lowercase: convertissez chaque terme en minuscules.Stemmer: Si cette option est activée, les termes de racine composés entièrement de lettres ASCII avec le stemming anglais regroupé. Cette étape ne fait pas la racine des termes CJK.
L'étape d'analyse spécifique au langage applique les règles suivantes :
Chinois
- Expansion des sous-mots : en mode
mixed, ajoutez les termes de deux et trois caractères que contient le dictionnaire groupé.
Japonais
- Filtrage par partie du discours : ignorer les particules, les verbes auxiliaires, les conjonctions, les mots de remplissage, les sons non verbaux, les symboles non alphabétiques et les segments marqués
その他,間投. - Conversion en forme de base : utilisez la forme de base du dictionnaire pour chaque segment reconnu restant, lorsqu’elle est disponible. Sinon, conservez sa forme de surface.
- Filtrage des mots vides : ignorer un terme qui correspond à la liste intégrée des mots fonctionnels japonais courants.
- Tige de katakana : supprimez un
ーde fin d'un terme d'au moins quatre caractères dont tous les caractères se trouvent dans le bloc katakana (U+30A0 à U+30FF).
Coréen
- Décomposition : Dans les modes
discardetmixed, divisez un segment composé, fléchi ou préanalysé reconnu lorsque le dictionnaire fournit ses composantes.discardémet les composantes à la place du terme complet, etmixedémet les deux. - Filtrage des parties du discours : appliquez le filtrage à l’ensemble du terme et à chaque composant indépendamment. Omettez les termes marqués comme particules, terminaisons, affixes, adverbes, déterminants, interjections, ponctuation, symboles ou formes non analysables.
- Conversion de lecture Hangul : utiliser la lecture Hangul du dictionnaire pour un terme complet retenu lorsqu’il est disponible. Les composants conservent leur forme de dictionnaire.
Le parseur de recherche textuelle de PostgreSQL découpe le texte aux espaces blancs et à la ponctuation avant d’appeler tokenizer_morph. Chaque jeton de parseur peut contenir jusqu’à 2046 octets, et les jetons plus longs sont ignorés avec un NOTICE. La plupart des caractères chinois, japonais et coréens utilisent 3 octets en UTF-8 ; ainsi, une séquence de plus de 682 de ces caractères sans espaces ni ponctuation est omise des résultats de to_tsvector.
Langues et modes pris en charge
Les modes disponibles dépendent du langage. Chaque exemple montre le texte source → termes émis :
Langue | Mode | Comportement | Exemple |
|---|---|---|---|
Chinois |
| Émet des mots issus d'une segmentation standard sans ajouter de termes de recherche plus courts. |
|
Chinois |
| Empêche les mots d'être segmentés de manière standard et ajoute des termes de recherche plus courts à partir de certains mots plus longs. |
|
Japonais |
| Favorise les composés de dictionnaire plus longs. |
|
Japonais |
| Produit des termes à granularité plus fine pour certains composés longs sans pour autant conserver leur forme complète. |
|
Coréen |
| Conserve les entrées de dictionnaire composées et fléchies comme des termes entiers. |
|
Coréen |
| Lorsqu’une forme composée ou fléchie peut être divisée, émet ses parties au lieu du terme complet. |
|
Coréen |
| Lorsqu’une forme composée ou fléchie peut être séparée, émet à la fois le terme complet et ses parties. |
|
En mode mixed, la query avec plainto_tsquery. Lorsqu’un mot de query produit plusieurs lexèmes, to_tsquery, websearch_to_tsquery et phraseto_tsquery les joignent à l’opérateur <->, ce qui nécessite des positions adjacentes. Le mode mixed insère des positions supplémentaires pour les termes additionnels. Ces conditions de phrase peuvent donc manquer des correspondances attendues. Pour les query basées sur la position, définissez une configuration personnalisée avec le mode none ou discard.
Utiliser les configurations intégrées
L'installation de l'extension crée ces configurations de recherche textuelle :
Configuration | Dictionnaire | Langue | Mode |
|---|---|---|---|
|
| Chinois |
|
|
| Japonais |
|
|
| Coréen |
|
Les trois dictionnaires définissent Stemmer = 'english' et utilisent Normalize = 'NFKC' et Lowercase = 'true' default.
Pour des exemples de bout en bout utilisant ces configurations, voir Texte CJK.
Définir une configuration personnalisée
Pour choisir un autre mode ou modifier les options default, créez un dictionnaire à partir du Template tokenizer_morph et une configuration de recherche de texte qui y fait correspondre les types de jetons PostgreSQL, comme illustré ci-dessous. Cet exemple utilise le mode chinois none pour les query de phrase :
CREATE TEXT SEARCH DICTIONARY chinese_none_dict (
TEMPLATE = tokenizer_ext.tokenizer_morph,
Language = 'chinese',
Mode = 'none',
Stemmer = 'english'
);
CREATE TEXT SEARCH CONFIGURATION chinese_none_cfg (COPY = pg_catalog.simple);
ALTER TEXT SEARCH CONFIGURATION chinese_none_cfg
ALTER MAPPING FOR asciiword, word, numword, hword_asciipart, hword_part, hword_numpart
WITH chinese_none_dict;
SELECT to_tsvector('chinese_none_cfg', '现代分布式文件系统架构')
@@ phraseto_tsquery('chinese_none_cfg', '分布式文件系统 架构');
Options
Spécifiez les options tokenizer_morph dans CREATE TEXT SEARCH DICTIONARY ou ALTER TEXT SEARCH DICTIONARY. Les noms d'option ne sont pas sensibles à la casse.
Option | Type | Par défaut | Description |
|---|---|---|---|
|
| Obligatoire | Sélectionne l’analyseur spécifique au langage. |
|
| Obligatoire | Contrôle la sortie composée et sous-mot. Les modes pris en charge dépendent de |
|
|
| Normalise le texte avant la segmentation. |
| booléen |
| Convertit les lexèmes émis en minuscules. |
|
| Aucun | Les radicaux ne sont que des lexèmes constitués entièrement de lettres ASCII. Omettez cette option pour désactiver la recherche de racine des mots en anglais. |
Utiliser le classement BM25 avec lakebase_text
Les configurations de recherche textuelle créées avec lakebase_tokenizer produisent des valeurs PostgreSQL tsvector standard compatibles avec lakebase_text. Pour utiliser le classement par pertinence BM25 et la récupération top-K, créez un index lakebase_bm25 sur la même colonne tsvector. Pour en savoir plus sur l'installation, la création d'index et la syntaxe de requête, consultez lakebase_text.