PostgreSQL に組み込まれているフルテキストインデックス機能は、中国語テキストを効果的に処理できません。このトピックでは、 および PolarDB for PostgreSQL (Oracle 互換) で zhparser エクステンションを使用して、効率的かつ正確な中国語のフルテキストインデックスを作成する方法について説明します。
中国語のトークン化の有効化
エクステンションを有効化します。
CREATE EXTENSION IF NOT EXISTS zhparser;中国語の形態素解析の構成を作成します。
-- zh_cfg という名前の構成を作成し、パーサとして zhparser を指定します。 CREATE TEXT SEARCH CONFIGURATION zh_cfg (PARSER = zhparser); -- 名詞 (n)、動詞 (v)、形容詞 (a) などの特定のトークンタイプにマッピングを追加します。 -- これにより 'simple' 辞書が使用されます。この辞書は、テキストを小文字に変換し、ストップワードをチェックします。 ALTER TEXT SEARCH CONFIGURATION zh_cfg ADD MAPPING FOR n,v,a,i,e,l WITH simple;グローバルパラメーターを設定します。
zhparserエクステンションには、調整可能なパラメーターが用意されています。これらのパラメーターは、ALTER ROLEまたはALTER DATABASEを使用して設定できます。-- 例: "multi-short phrase" モードを有効にします。このモードは、隣接する単一文字を結合してより長い単語を形成しようとします。 ALTER ROLE ALL SET zhparser.multi_short = ON;形態素解析の結果をテストします。
-- 1. 基本的な字句解析 (ts_parse) をテストします。 SELECT * FROM ts_parse('zhparser', 'In 2011, affordable housing entered a larger-scale construction phase.'); -- 2. テキストを単語ベクトル (to_tsvector) に変換するテストをします。 -- 先ほど作成した 'zh_cfg' 構成を使用します。 SELECT to_tsvector('zh_cfg', 'Compared to 2011, the pressure on funding for affordable housing construction in 2012 will be more severe.'); -- 3. クエリ文字列をクエリツリー (to_tsquery) に変換するテストをします。 -- 'affordable housing' & 'funding' & 'pressure' SELECT to_tsquery('zh_cfg', 'affordable housing & funding & pressure');
フルテキストインデックスの作成と使用
サンプルテーブルとデータを準備します:
-- サンプルテーブル t1 を作成します。 CREATE TABLE t1 ( id SERIAL PRIMARY KEY, name TEXT ); -- テストデータを挿入します。 INSERT INTO t1 (name) VALUES ('中央政府は手頃な価格の住宅の建設と投資を増やす'), ('手頃な価格の住宅に対する資金圧力が厳しい'), ('防火と盗難防止はセキュリティ作業のフォーカスです');ターゲットフィールドに GIN インデックスを作成します:
t1テーブルのnameフィールドに GIN インデックスを作成します。このインデックスはzh_cfg構成に基づいています。-- 'zh_cfg' 構成を使用して name フィールドに GIN インデックスを作成します。 CREATE INDEX idx_gin_t1_name ON t1 USING gin (to_tsvector('zh_cfg', name));効率的なフルテキストインデックスクエリを実行します:
@@演算子を使用してクエリを実行できます。WHERE句のto_tsvector式は、CREATE INDEX文の式と完全に一致する必要があります。これにより、オプティマイザーが作成されたインデックスを確実に使用するようになります。-- 例 1: "affordable housing" を含むレコードをクエリします。 -- クエリ式 to_tsvector('zh_cfg', name) はインデックス定義と完全に一致するため、インデックスが効率的に使用されます。 SELECT name FROM t1 WHERE to_tsvector('zh_cfg', name) @@ to_tsquery('zh_cfg', 'affordable housing'); -- 例 2: "affordable housing" と "funding" の両方を含むレコードをクエリします (& 演算子を使用)。 SELECT name FROM t1 WHERE to_tsvector('zh_cfg', name) @@ to_tsquery('zh_cfg', 'affordable housing & funding'); -- 例 3: "fire prevention" を含むレコードをクエリします。 SELECT name FROM t1 WHERE to_tsvector('zh_cfg', name) @@ to_tsquery('zh_cfg', 'fire prevention');