全部產品
Search
文件中心

AnalyticDB:Nova BM25索引和詞典管理

更新時間:Aug 13, 2026

本文介紹如何建立和管理 Nova BM25 全文檢索索引索引,以及如何配置中文分詞詞典。Nova BM25 是 AnalyticDB PostgreSQL 提供的高效能全文檢索索引方案,基於 nova_bm25 擴充實現,SQL 函數位於 bm25 schema,索引存取方法名為 nova_bm25

有關 Nova BM25 的快速入門手冊,請參見Nova BM25快速開始。有關完整的函數 API 參考,請參見Nova BM25 Function API參考

建立索引

建立樣本表

以下樣本建立一個包含多種欄位類型的業務表,涵蓋文本、數值、時間戳記和布爾類型,作為後續索引建立的參考:

CREATE TABLE docs (
    id         bigint PRIMARY KEY,
    title      text,
    body       text,
    category   text,
    rating     integer,
    publish_at timestamp,
    in_stock   boolean
) DISTRIBUTED BY (id);

建立 BM25 索引

在樣本表上建立 Nova BM25 索引,通過 WITH 子句為每種欄位類型指定相應的索引配置。正確的欄位配置直接影響檢索的準確性和效能:

CREATE INDEX docs_bm25_idx ON docs
USING nova_bm25 (title, body, category, rating, publish_at, in_stock)
WITH (
    text_fields = '{
      "title": {"tokenizer": {"type": "jieba"}},
      "body": {"tokenizer": {"type": "jieba"}},
      "category": {"tokenizer": {"type": "keyword"}}
    }',
    numeric_fields = '{"rating": {}}',
    datetime_fields = '{"publish_at": {}}',
    boolean_fields = '{"in_stock": {}}'
);

索引欄位配置說明

建立索引時,需要通過 WITH 子句為每個參與檢索的欄位指定配置。下表列出各類欄位配置參數的詳細說明:

配置參數

適用欄位類型

說明

配置樣本

text_fields

text、varchar

文字欄位,需指定 tokenizer 類型以控制分詞方式

{"title": {"tokenizer": {"type": "jieba"}}}

numeric_fields

integer、bigint、float 等

數值欄位,支援範圍查詢和數值排序

{"rating": {}}

datetime_fields

timestamp、date

時間欄位,支援時間範圍查詢

{"publish_at": {}}

boolean_fields

boolean

布爾欄位,支援 true/false 過濾

{"in_stock": {}}

json_fields

json、jsonb

JSON 欄位,支援對 JSON 內部索引值建立索引

{"metadata": {}}

選擇欄位配置

為每個欄位選擇正確的配置類型是構建高效全文索引的關鍵。配置類型決定了欄位的檢索行為和可用的查詢方式。下表列出常見的欄位用途及其推薦的配置方式:

欄位用途

配置方式

樣本

中文標題、本文

text_fields,使用 jieba

title、body

分類、狀態等整值欄位

text_fields,使用 keyword

category、status

評分、價格等數值欄位

numeric_fields

rating、price

發布時間等時間欄位

datetime_fields

publish_at

是否上架等布爾欄位

boolean_fields

in_stock

JSON 欄位

json_fields

metadata

文字欄位 tokenizer 選擇指南

為文字欄位選擇正確的 tokenizer 直接影響檢索效果。下表列出常用的 tokenizer 類型及其適用情境:

Tokenizer 類型

適用情境

說明

jieba

中文文本

基於結巴分詞,支援中文語義分詞,可載入自訂字典

default

英文文本

按空格和標點符號分詞,適用於英文等西文語言

keyword

精確匹配欄位

不分詞,將整個欄位值作為一個檢索單元,適用於分類、標籤、狀態代碼等

ngram

細粒度匹配

按 n-gram 切分文本,支援部分匹配和模糊檢索,適用於首碼或子串搜尋情境

驗證分詞效果

建立索引後,建議使用分詞調試函數驗證實際的分詞效果是否符合預期。以下樣本展示如何查看 jieba 分詞器對輸入文本的分詞結果:

SELECT * FROM bm25.debug_tokenizer('雲原生資料庫', 'jieba');

查詢增量資料

Nova BM25 支援近即時查詢模式,新寫入或更新的資料在短暫的延遲後即可被檢索到。您可以通過以下參數和命令控制增量資料的查詢行為,在資料新鮮度與查詢效能之間取得平衡。

通過 query_skip_mutable 參數控制是否查詢最新增量資料:

參數

說明

query_skip_mutable

預設值為 true,使用預設近即時查詢模式。設定為 false 時包含最新增量資料,但可能增加查詢延遲。

在建立索引時設定該參數:

CREATE INDEX docs_bm25_idx ON docs
USING nova_bm25 (title, body)
WITH (text_fields = '{"title": {"tokenizer": {"type": "jieba"}}, "body": {"tokenizer": {"type": "jieba"}}}', query_skip_mutable = false);

通過 ALTER INDEX 修改該參數:

ALTER INDEX docs_bm25_idx SET (query_skip_mutable = false);
ALTER INDEX docs_bm25_idx SET (query_skip_mutable = true);

通過 SET 命令在會話層級控制:

SET nova_bm25.query_include_mutable = on;
RESET nova_bm25.query_include_mutable;

修改和重建索引

Nova BM25 索引建立後,其欄位配置(如 tokenizer 類型、欄位對應等)不支援通過 ALTER INDEX 直接修改。如需變更索引配置,必須先刪除索引再重新建立。

刪除並重新建立索引以修改配置:

DROP INDEX docs_bm25_idx;
-- 重新建立
CREATE INDEX docs_bm25_idx ON docs USING nova_bm25 (...) WITH (...);

如果索引配置無需變更,但需要清理索引片段或重新整理索引資料,可以使用 REINDEX 命令重建索引:

REINDEX INDEX docs_bm25_idx;

中文詞典管理

Nova BM25 使用 jieba 分詞器處理中文文本。為了滿足業務情境中的專業術語和同義字檢索需求,您可以通過詞典管理功能自訂分詞行為。

添加自訂詞條

向 jieba 分詞器的自訂字典中添加專業術語或業務詞彙,使分詞器能夠正確識別這些詞條,避免被錯誤切分。添加後需要重新載入詞典使其生效:

SELECT bm25.add_dict_word('jieba', 'product_terms', '雲原生資料庫', 10000, 'n');
SELECT bm25.reload_dict('jieba', 'product_terms');

配置同義字

配置同義字詞典,將多個含義相近的詞條映射到相同的檢索結果,從而擴大搜尋覆蓋面,提升召回率:

SELECT bm25.add_dict_word('synonym', 'product_synonyms', 'postgresql,postgres,pg');
SELECT bm25.reload_dict('synonym', 'product_synonyms');

驗證詞典效果

添加自訂詞條或同義字後,建議通過分詞調試函數驗證詞典配置是否生效,確認詞條被正確識別:

SELECT * FROM bm25.debug_tokenizer('雲原生資料庫', 'jieba');

日常維護

定期執行維護操作有助於保持 Nova BM25 索引的查詢效能和資料一致性。下表列出常用的維護操作及其用途:

操作

說明

VACUUM

回收已刪除資料佔用的空間,最佳化表格儲存體

REINDEX

重建索引以消除片段,恢複查詢效能

DROP INDEX

刪除不再使用的索引,釋放儲存空間

VACUUM docs;
REINDEX INDEX docs_bm25_idx;
DROP INDEX docs_bm25_idx;