全部產品
Search
文件中心

PolarDB:使用中文分詞

更新時間:Jan 06, 2026

本文將詳細介紹如何在PolarDB PostgreSQL版(相容Oracle)中,利用zhparser擴充來解決 PostgreSQL 內建全文檢索索引功能無法有效處理中文的難題。通過整合此擴充,您可以輕鬆實現高效、精準的中文全文檢索索引。

啟用中文分詞

  • 啟用擴充。

    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 進行設定。

    -- 樣本:開啟“多元短語”模式,會嘗試組合相鄰的單字以形成更長的詞
    ALTER ROLE ALL SET zhparser.multi_short = ON;
  • 測試分詞效果。

    -- 1. 測試基本的詞法分析 (ts_parse)
    SELECT * FROM ts_parse('zhparser', '2011年,保障房進入了更大規模的建設階段。');
    
    -- 2. 測試將文本轉換為詞向量 (to_tsvector)
    --    這裡使用我們剛剛建立的配置 'zh_cfg'
    SELECT to_tsvector('zh_cfg', '與2011年相比,2012年的保障房建設在資金配套上的壓力將更為嚴峻。');
    
    -- 3. 測試將查詢字串轉換為查詢樹 (to_tsquery)
    --    '保障房' 和 '資金' 和 '壓力'
    SELECT to_tsquery('zh_cfg', '保障房 & 資金 & 壓力');
    

建立並使用全文索引

  1. 準備樣本表和資料:

    -- 建立一個樣本表 t1
    CREATE TABLE t1 (
        id SERIAL PRIMARY KEY,
        name TEXT
    );
    
    -- 插入一些測試資料
    INSERT INTO t1 (name) VALUES
    ('中央加大保障房的建設和投入力度'),
    ('保障房資金配套壓力嚴峻'),
    ('防火防盜是安全工作的重點');
  2. 為目標欄位建立 GIN 索引:

    我們將為 t1 表的 name 欄位建立一個基於 zh_cfg 配置的 GIN 索引。

    -- 使用我們建立的 'zh_cfg' 配置為 name 欄位建立 GIN 索引
    CREATE INDEX idx_gin_t1_name ON t1 USING gin (to_tsvector('zh_cfg', name));
  3. 執行高效的全文檢索索引查詢:

    使用 @@ 操作符進行查詢。關鍵在於 WHERE 子句中的 to_tsvector 運算式必須與 CREATE INDEX 中的運算式完全一致,這樣才能確保最佳化器能夠使用我們建立的索引。

    -- 樣本1:查詢包含“保障房”的記錄
    -- 查詢運算式 to_tsvector('zh_cfg', name) 與索引定義完全符合,會高效利用索引
    SELECT name FROM t1 WHERE to_tsvector('zh_cfg', name) @@ to_tsquery('zh_cfg', '保障房');
    
    -- 樣本2:查詢同時包含“保障房”和“資金”的記錄 (使用 & 操作符)
    SELECT name FROM t1 WHERE to_tsvector('zh_cfg', name) @@ to_tsquery('zh_cfg', '保障房 & 資金');
    
    -- 樣本3:查詢包含“防火”的記錄
    SELECT name FROM t1 WHERE to_tsvector('zh_cfg', name) @@ to_tsquery('zh_cfg', '防火');