PostgreSQL のデフォルトのテキストパーサは、スペースおよび句読点を基準に文字列を分割します。これは、単語の境界がスペースで明示される欧州言語では適切に機能します。一方、中国語は単語間にスペースが存在しないため、デフォルトのパーサでは文全体が 1 つのトークンとして扱われ、個々の単語をマッチさせることができません。zhparser 拡張は、専用の中国語辞書と分割アルゴリズムを適用することでこの課題を解決し、AnalyticDB for PostgreSQL における中国語コンテンツに対する全文検索を可能にします。
前提条件
開始する前に、以下の条件を満たしていることを確認してください。
AnalyticDB for PostgreSQL インスタンス
インスタンスの 拡張 ページに zhparser 拡張がインストール済みであること(詳細については、「拡張のインストール、更新、アンインストール」をご参照ください)
PostgreSQL における全文検索の仕組み
PostgreSQL の全文検索は、以下の 2 つのデータの型に依存します。
tsvector — 正規化された語彙(lexeme)とその位置情報を格納する、前処理済みのドキュメント表現
tsquery — 検索クエリの式
代表的なクエリパターンは以下の 2 つです。
直接クエリ:
SELECT name FROM <table>
WHERE to_tsvector('english', name) @@ to_tsquery('english', 'friend');パフォーマンス向上のための一般化逆インデックス (GIN) インデックス:
CREATE INDEX <idx_name> ON <table> USING gin(to_tsvector('english', name));zhparser を構成した後は、上記の両方のパターンにおいて、'english' を 'zh_cn' に置き換えることで、中国語の形態素解析を有効化できます。
zhparser の構成
ステップ 1:テキスト検索構成の作成
拡張をインストールした後、zhparser をパーサとして使用するテキスト検索構成 zh_cn を作成します。
CREATE TEXT SEARCH CONFIGURATION zh_cn (PARSER = zhparser);構成が正しく作成されたかを確認するには、psql で \dF または \dFp を実行します。
ステップ 2:利用可能なトークン種別の一覧表示
zhparser は中国語テキストを 26 種類のトークン種別に分類します。以下のコマンドを実行すると、一覧を表示できます。
SELECT ts_token_type('zhparser');出力結果には、すべての利用可能な種別がリストされます。
tokid | alias | description
-------+-------+--------------------
97 | a | 形容詞
98 | b | 区別語
99 | c | 接続詞
100 | d | 副詞
101 | e | 感嘆詞
102 | f | 方位詞
103 | g | 根語
104 | h | 頭語
105 | i | 成語
106 | j | 略語
107 | k | 尾語
108 | l | 仮成語
109 | m | 数詞
110 | n | 名詞
111 | o | 擬音語
112 | p | 前置詞
113 | q | 量詞
114 | r | 代名詞
115 | s | スペース
116 | t | 時間語
117 | u | 助動詞
118 | v | 動詞
119 | w | 句読点
120 | x | 不明語
121 | y | 情態動詞
122 | z | 状態語
(26 rows)現在の zh_cn 構成を確認するには:
SELECT * FROM pg_ts_config_map
WHERE mapcfg = (SELECT oid FROM pg_ts_config WHERE cfgname = 'zh_cn');ステップ 3:トークン種別の辞書へのマッピング
インデックス対象とするトークン種別を指定するマッピングを追加します。以下の例では、名詞、動詞、形容詞、成語、感嘆詞、仮成語を simple 辞書にマッピングしています。
ALTER TEXT SEARCH CONFIGURATION zh_cn ADD MAPPING FOR n,v,a,i,e,l WITH simple;これらのマッピングを削除するには:
ALTER TEXT SEARCH CONFIGURATION zh_cn DROP MAPPING IF EXISTS FOR n,v,a,i,e,l;ステップ 4:分割結果の検証
to_tsvector および to_tsquery を zh_cn 構成でテストします。
SELECT to_tsvector('zh_cn', '有两种方法进行全文检索'); to_tsvector
--------------------------------------
'全文检索':4 '方法':2 '有':1 '进行':3
(1 row)SELECT to_tsquery('zh_cn', '有两种方法进行全文检索'); to_tsquery
-------------------------------------
'有' & '方法' & '进行' & '全文检索'
(1 row)カスタム辞書
zhparser では、ドメイン固有の用語やストップワードを追加するためのカスタム辞書テーブル — zhparser.zhprs_custom_word — をサポートしています。このテーブルは、拡張をインストールした際に自動的に作成されます。
テーブル構造
CREATE TABLE zhparser.zhprs_custom_word
(
word text PRIMARY KEY, -- カスタム単語
tf FLOAT DEFAULT '1.0', -- 詞頻 (TF)。デフォルト値:1.0。
idf FLOAT DEFAULT '1.0', -- 逆文書頻度 (IDF)。デフォルト値:1.0。
attr CHAR DEFAULT '@', CHECK(attr = '@' OR attr = '!') -- 単語種別:@(新規単語)、!(ストップワード)。
);カスタム辞書の構成
マッピングを追加して、unknown トークン(タイプ x)がカスタム辞書で検索されるようにします:
ALTER TEXT SEARCH CONFIGURATION zh_cn ADD MAPPING FOR x WITH simple;単語の追加および削除
カスタム辞書に単語を追加します。
INSERT INTO zhparser.zhprs_custom_word(word, attr) VALUES('两种方法', '@');単語を削除します。
DELETE FROM zhparser.zhprs_custom_word WHERE word = '两种方法';すべての登録内容を照会します。
SELECT * FROM zhparser.zhprs_custom_word;再読み込みと検証
zhparser.zhprs_custom_word テーブルを変更した後は、変更を有効化するためにテーブルを再読み込みする必要があります。
SELECT sync_zhprs_custom_word();変更前後で同一のクエリを実行し、効果を確認します。
SELECT to_tsvector('zh_cn', '有两种方法进行全文检索');`两种方法` を追加する前 — 文字列は個々のトークンに分割されます。
to_tsvector
--------------------------------------
'全文检索':4 '方法':2 '有':1 '进行':3
(1 row)`两种方法` を追加した後 — 文字列は単一のユニットとして扱われます。
to_tsvector
----------------------------------------------
'两种方法':2 '全文检索':4 '有':1 '进行':3
(1 row)次のステップ
全文検索 — PostgreSQL 全文検索のリファレンス
テキスト検索関数および演算子 — 全文検索に使用する関数および演算子