lakebase_tokenizer
ベータ版
6月15日より、LakebaseはGCPでベータとして利用可能です。サポートされているリージョンについては、「リージョンの可用性」を参照してください。
lakebase_tokenizer拡張機能は、LakebaseのPostgreSQL全文検索に構成可能なトークン化を追加し、中国語、日本語、韓国語 (CJK) テキストの単語全体の処理と形態素解析を含みます。拡張機能を使用して構築されたテキスト検索構成は、 to_tsvector、 @@ 演算子、ランク付け関数、およびGINインデックスと連動します。生成された tsvector 値を lakebase_text とともに使用してBM25ランク付けを行うこともできます。
拡張機能は、PostgreSQLの標準テキスト検索辞書インターフェイスを通じてtokenizer_wholewordおよびtokenizer_morphテンプレートを提供します。正規化、ストップワード、類義語、英語のステミングなど、単語の完全一致処理にはtokenizer_wholewordを使用します。CJK形態素解析にはtokenizer_morphを使用します。
インストール
データベースに拡張機能をインストールします。このページの例では、拡張機能のオブジェクトを識別しやすくするために専用のスキーマを使用しています:
CREATE SCHEMA IF NOT EXISTS tokenizer_ext;
CREATE EXTENSION IF NOT EXISTS lakebase_tokenizer WITH SCHEMA tokenizer_ext;
拡張機能は再配置可能です。インストール時に tokenizer_ext を別のスキーマに置き換えることができます。
拡張機能をアップグレードする
新しいLakebase Searchリリースでは、機能、修正、パフォーマンスの改善が追加される場合があります。PostgreSQLは、インストール済みの拡張機能のバージョンを自動的には更新しません。インストール済みバージョンと利用可能な最新バージョンを確認します:
SELECT installed_version, default_version
FROM pg_available_extensions
WHERE name = 'lakebase_tokenizer';
拡張機能を最新の利用可能なバージョンに更新します。
ALTER EXTENSION lakebase_tokenizer UPDATE;
ALTER EXTENSION 保存された tsvector 値を再生成したり、依存する GIN または lakebase_bm25 インデックスを再構築したりしません。更新によってトークン化の出力が変更される場合は、保存された tsvector 値を再生成し、必要なインデックスのメンテナンスについてはリリースノートに従ってください。
0.1.x からのアップグレードから 0.2.0 に変更してもトークン化の出力は変わりません。バージョン 0.2.0 ではtokenizer_morph Templateと組み込みの CJK 設定が追加されます。既存の設定は変更されないため、tsvector 値を再生成したりインデックスを再構築したりする必要はありません。
クイック起動
テキストの言語に基づいてパスを選択してください:
- 英語やその他の空白で区切られた言語については、
tokenizer_wholewordTemplateから辞書を作成します。 - 中国語、日本語、または韓国語のテキストには、組み込み構成を使用します。辞書を作成する必要はありません。
単語単位のテキスト
次の例では、tokenizer_wholeword Templateからディクショナリを作成し、テキスト検索構成で一般的なPostgreSQLトークンタイプをそれにマッピングします。
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;
tsvectorを生成し、GIN インデックスを作成し、全文クエリーを実行するための構成を使用します。
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é');
ドキュメントとクエリーに同じテキスト検索構成を使用することで、両側で同じトークン化戦略とオプションが適用されるようにします。
CJKテキスト
拡張機能をインストールすると、tokenizer_chinese、tokenizer_japanese、およびtokenizer_koreanのテキスト検索構成が作成されます。それらのいずれかを直接使用して tsvector を生成し、GIN インデックスを作成し、全文クエリーを実行します。
- 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
仕組み
PostgreSQL のテキスト検索パーサーによって辞書に渡された各トークンに対して、tokenizer_wholeword は次の操作を適用します:
Lowercase:トークンを小文字に変換します。Normalize:Unicode 正規化を適用します。StripAccents:アクセントを削除します。EnglishPossessive: Remove an English possessive suffix when at least one character remains.Stopwords:構成済みのストップワードにトークンが一致した場合、語彙素を出力せず、処理を停止します。生成されたtsvectorからトークンが省略されます。Synonyms: 設定された置換を出力し、トークンがシノニムと一致する場合は処理を停止します。Stemmer: 一致する同義語がなく、ステミングが有効な場合は、English ステマーを適用します。
ストップワードとシノニムを追加する
The tokenizer_wholeword Template は、拡張機能で管理される SQL テーブル lakebase_tokenizer_stopwords および lakebase_tokenizer_synonyms からカスタムのストップワードと類義語を読み込むことができます。name 列は、Stopwords または 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');
tokenizer_wholeword 辞書の作成時または変更時にセットを参照します。
ALTER TEXT SEARCH DICTIONARY documents_dict (
Stopwords = 'app_stopwords',
Synonyms = 'app_synonyms'
);
この拡張機能は、Lowercase、Normalize、StripAccents、EnglishPossessiveを適用した後、Stemmerを適用する前に、各トークンとストップワードおよび同義語のソースワードを比較します。カタログエントリは自動的に変換されないため、有効にしたオプションによって生成された正確な形式で保存します:
Lowercase = 'true'では、小文字のエントリを使用してください。Lowercase = 'false'では、大文字と小文字がトークンと一致している必要があります。Normalizeを有効にして、選択した Unicode 正規化フォームにエントリーを格納します。StripAccents = 'true'を使用して、アクセントを除去した形式で保存します。たとえば、cafeを保存してcaféに一致させます。- ステミングの前にフォームを保存します。たとえば、
Stemmer = 'english'を使用した場合、runエントリはrunningと一致しません。runningを追加してトークンをフィルターまたは置換します。
セット名には最大256バイトを含めることができます。単語と同義語には最大1,024バイトを含めることができます。名前付きのストップワードまたは同義語セットには、それぞれ最大100,000行を含めることができます。
シノニムの置換は、保存されたとおりに出力され、ステマーによる処理は行われません。シノニムは、各ソースワードに対して 1 つの置換をサポートします。複数の単語からなる置き換えを 1 つの語lexemeとして表現するには、united_states のようにアンダースコアなどの区切り文字を使用します。
セットを変更した後は、そのセットを参照する各辞書の所有者が no-op ALTER TEXT SEARCH DICTIONARY を実行して強制的に再読み込みを行う必要があります:
ALTER TEXT SEARCH DICTIONARY documents_dict (dummy);
dummyオプションはtokenizer_wholewordに存在しません。値を省略すると、PostgreSQLはこの存在しないオプションを削除するように求められます。これにより、辞書の構成されたオプションを変更せずにキャッシュが無効になります。
辞書をリロードした後、ソース行を書き直して保存された tsvector 値を再生成します。
UPDATE documents SET body = body;
ロールとアクセス
2 つのロールを使用して、アプリケーションアクセスをトークナイザーの管理から分離します。
app_role既存のディクショナリを使用します。関連するスキーマに対してUSAGEが、拡張カタログテーブルに対してSELECTが必要ですが、ディクショナリを所有する必要はありません。tokenizer_adminストップワードとシノニムのセットを管理し、辞書とテキスト検索構成を作成して所有し、セットの変更後に reload コマンドを実行します。
拡張機能のスキーマとカタログのテーブルへのアクセス権を付与します。
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 また、辞書とテキスト検索構成が保存されているスキーマに対するCREATEも必要です。これらのオブジェクトをtokenizer_adminとして作成するか、所有権をに譲渡します。カタログテーブルへの書き込みアクセス権では、既存の辞書の所有権は付与されません。
オプション
CREATE TEXT SEARCH DICTIONARYまたはALTER TEXT SEARCH DICTIONARYでtokenizer_wholewordオプションを指定します。オプション名では大文字と小文字が区別されません。
オプション | Type | デフォルト | 説明 |
|---|---|---|---|
| boolean |
| 他の操作を適用する前に、トークンを小文字に変換します。 |
|
|
| 選択した Unicode 正規化形式を適用します。これにより表現が正規化されますが、文字は削除されません。たとえば、 |
| boolean |
| 接尾辞の前に少なくとも1つの文字がある場合、末尾の |
| boolean |
| NFKD正規化を適用し、結合文字を削除します。たとえば、 |
| 名前を設定 | なし | Uses the named set from |
| 名前を設定 | なし |
|
|
| なし | バンドル版 Snowball 3.1.0 を使用します英語のステマー。ステミングを無効にするには、このオプションを省略します。ステマーにはストップワードリストが含まれていません。 |
Catalog テーブル
テーブル | 列 | 説明 |
|---|---|---|
|
|
|
|
|
|
Template: tokenizer_morph
tokenizer_morphTemplateは、PostgreSQL全文検索で中国語、日本語、韓国語のテキストにトークン化のサポートを提供します。組み込みのテキスト検索構成を使用するか、カスタム構成を定義して、用語の生成を制御します。
仕組み
tokenizer_morph Linderaアナライザーを使用し、中国語にはJieba、日本語にはIPADIC、韓国語にはMeCab KoDicの辞書をバンドルしています。
韓国語パーサーのトークンについては、tokenizer_morphは最初にㆍ (U+318D) をトークン境界に置き換えます。
PostgreSQLのテキスト検索パーサーによってディクショナリに渡されるトークンごとに、tokenizer_morph はこれらの操作を順番に適用します。
Normalize:パーサートークンにUnicode正規化を適用します。Language:選択した言語アナライザーでパーサートークンをセグメント化します。- 記号フィルター:英字または数字を含まないセグメントを破棄します。
- 言語固有の分析: 以下の説明に従って、残りの各セグメントを0個以上の用語に変換します。
Lowercase: 各用語を小文字に変換します。Stemmer: 有効にすると、バンドルされた日本語ステマーを使用して、完全にASCII文字で構成される用語をステミングします。このステップでは、CJK用語はステミングしません。
言語固有の分析ステップでは、以下のルールが適用されます。
中国語
- サブワード拡張:
mixedモードでは、バンドルされている辞書に含まれる2文字および3文字の用語を追加します。
日本語
- 品詞フィルタリング:認識された助詞、助動詞、接続詞、フィラー、非言語的音声、非アルファベット記号、およびタグ付けされたセグメント
その他,間投を破棄します。 - 基本形変換:利用可能な場合は、残りの認識されたセグメントの辞書の基本形を使用します。それ以外の場合は、表層形を保持します。
- ストップワードフィルタリング: 日本語の一般的な機能語の組み込みリストに一致する単語を破棄します。
- カタカナ語尾の正規化:すべての文字がカタカナブロック(U+30A0からU+30FFまで)に含まれ、少なくとも4文字以上の用語から、末尾の
ーを削除します。
韓国語
- 分解:
discardおよびmixedモードで、辞書がコンポーネントを提供する場合に、認識された複合語、屈折語、または事前分析されたセグメントを分割します。discardは完全な用語の代わりにコンポーネントを生成し、mixedは両方を生成します。 - 品詞フィルタリング:完全な用語と各構成要素に独立してフィルタリングを適用します。助詞、語尾、接辞、副詞、限定詞、間投詞、句読点、記号、または分析不能な形式としてタグ付けされた用語を省略します。
- ハングル読み変換:辞書のハングル読みが利用可能な場合は、保持されている完全な用語にその読みを使用します。コンポーネントは辞書形式を維持します。
PostgreSQLのテキスト検索パーサーは、tokenizer_morphを呼び出す前に、空白と句読点でテキストを分割します。各パーサートークンは最大2046バイトまで格納でき、それより長いトークンはNOTICEでスキップされます。ほとんどの中国語、日本語、韓国語の文字はUTF-8で3バイトを使用するため、空白や句読点なしでこれらの文字が682文字以上のランはto_tsvectorの結果から省略されます。
サポートされている言語とモード
使用できるモードは言語によって異なります。各例は、ソーステキスト → 出力された用語を示しています。
言語 | モード | 挙動 | 例 |
|---|---|---|---|
中国語 |
| より短い検索語を追加することなく、標準のセグメンテーションから単語を生成します。 |
|
中国語 |
| 標準的なセグメンテーションから単語を保持し、長い単語から短い検索語を追加します。 |
|
日本語 |
| より長い辞書の複合語を好みます。 |
|
日本語 |
| 一部の長い複合語のより細かい用語を生成しますが、その完全な形式は保持しません。 |
|
韓国語 |
| 複合辞書エントリおよび活用形辞書エントリを単語全体として保持します。 |
|
韓国語 |
| 複合語や屈折形を分割できる場合、完全な用語の代わりにその構成要素を出力します。 |
|
韓国語 |
| 複合語または語形変化した形式を分割できる場合は、完全な語とそれらの部分の両方を出力します。 |
|
mixedモードで、plainto_tsqueryを使用してクエリーします。1つのクエリー単語から複数の語彙素が生成される場合、to_tsquery、websearch_to_tsquery、およびphraseto_tsqueryは<->演算子でそれらを結合します。これには隣接する位置が必要です。mixedモードは追加の用語のために余分な位置を挿入するため、これらのフレーズ条件は予期される一致を見逃す可能性があります。位置ベースのクエリーの場合、noneまたはdiscardモードでカスタム構成を定義します。
組み込みの設定を使用する
拡張機能をインストールすると、以下のテキスト検索構成が作成されます:
構成 | 辞書 | 言語 | モード |
|---|---|---|---|
|
| 中国語 |
|
|
| 日本語 |
|
|
| 韓国語 |
|
3つの辞書すべてがStemmer = 'english'をセットし、default Normalize = 'NFKC'とLowercase = 'true'を使用します。
これらの設定を使用するエンドツーエンドの例については、CJKテキストを参照してください。
カスタム構成の定義
別のモードを選択するか、defaultのオプションを変更するには、以下に示すように、tokenizer_morph Templateから辞書を作成し、PostgreSQL トークン型をそのTemplateにマップするテキスト検索構成を作成します。この例では、句クエリーに中国語 none モードを使用しています。
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', '分布式文件系统 架构');
オプション
CREATE TEXT SEARCH DICTIONARYまたはALTER TEXT SEARCH DICTIONARYでtokenizer_morphオプションを指定します。オプション名では大文字と小文字が区別されません。
オプション | Type | デフォルト | 説明 |
|---|---|---|---|
|
| 必須 | 言語固有のアナライザーを選択します。 |
|
| 必須 | 複合およびサブワードの出力を制御します。サポートされているモードは |
|
|
| セグメンテーションの前にテキストを正規化します。 |
| boolean |
| 放出されたレキサームを小文字に変換します。 |
|
| なし | 完全にASCII文字で構成されている語彙素のみをステミングします。英語のステミングを無効にするには、このオプションを省略します。 |
lakebase_text で BM25 ランキングを使用する
lakebase_tokenizerで構築されたテキスト検索構成は、lakebase_textと互換性のある標準の PostgreSQL tsvector 値を生成します。BM25 関連性ランキングとトップ K 取得を使用するには、同じ tsvector 列に lakebase_bm25 インデックスを作成します。インストール、インデックスの作成、クエリー構文については、lakebase_text を参照してください。