全部產品
Search
文件中心

AnalyticDB:Nova BM25快速開始

更新時間:Aug 13, 2026

BM25 是資訊檢索領域經典的相關性排序演算法,通過詞頻、文檔長度和逆文檔頻率衡量關鍵詞與文檔的匹配程度,是 Elasticsearch 等搜尋引擎預設排序的基礎。Nova BM25 將該能力以原生索引的形式內建到 AnalyticDB PostgreSQL 中:您只需對文本列建立一個 nova_bm25 索引,即可在標準 SQL 裡完成中文分詞、關鍵詞召回、短語匹配和相關性排序,並可與分類、數值、時間等結構化條件以及向量檢索自由組合,無需引入外部搜尋系統。本文介紹如何在 AnalyticDB PostgreSQL 中安裝 Nova BM25 擴充並完成第一個中文全文檢索索引樣本。完成本文的操作後,您將掌握按相關性排序的全文檢索索引 SQL 編寫方法。

Nova BM25 的 SQL 函數位於 bm25 schema 下,索引存取方法名為 nova_bm25

前提條件

  • AnalyticDB PostgreSQL 執行個體版本為 7.5.1.0 及以上,且已開啟向量檢索引擎最佳化

  • 當前nova_bm25 外掛程式暫未開放控制台自助安裝。如需使用,請提交工單,由支援人員協助完成執行個體升級與安裝。

操作步驟

步驟一:準備樣本資料

建立一張樣本表並寫入測試資料,用於後續全文檢索索引操作。

DROP TABLE IF EXISTS docs;

CREATE TABLE docs (
    id         BIGINT PRIMARY KEY,
    title      TEXT,
    body       TEXT,
    category   TEXT,
    rating     INT,
    publish_at TIMESTAMP
) DISTRIBUTED BY (id);

INSERT INTO docs(id, title, body, category, rating, publish_at) VALUES
    (1, '資料庫系統設計', 'PostgreSQL 支援全文檢索索引和交易處理', 'tech', 5, '2024-01-01 10:00:00'),
    (2, '搜尋引擎開發',   'BM25 排序用於全文檢索索引相關性計算',   'tech', 5, '2024-02-01 10:00:00'),
    (3, '向量檢索實踐',   '混合檢索結合向量召回和關鍵詞召回',  'tech', 4, '2024-03-01 10:00:00'),
    (4, '使用者Portrait analysis',   '即時畫像處理用於推薦系統',          'biz',  3, '2024-04-01 10:00:00'),
    (5, '中文標點測試',   '資料庫,全文檢索索引;查詢最佳化!BM25 排名。', 'tech', 4, '2024-05-01 10:00:00');

實際業務表中無需使用樣本中的欄位名。只需將需要全文檢索索引的文本列以及用於過濾的分類、數值、時間列納入 BM25 索引即可。

步驟二:建立中文 BM25 索引

為樣本表建立 BM25 索引,並根據欄位用途配置不同的分詞器和欄位類型。

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

上述 WITH 配置根據欄位用途進行選擇。其中 text_fields 中的 tokenizer.type 指定文字欄位使用的分詞器:

  • 需要全文檢索索引的中文文本列(如本文、標題),配置在 text_fields 中,並使用 jieba 分詞。

  • 需要精確匹配的文本列(如分類、狀態、租戶、枚舉),同樣配置在 text_fields 中,但使用 keyword tokenizer,按整值匹配而不進行分詞。

  • 數值列(如評分、價格),配置在 numeric_fields 中。

  • 時間列(如發布時間、更新時間),配置在 datetime_fields 中。

步驟三:執行第一條查詢

使用以下 SQL 在 body 欄位上執行 BM25 全文檢索索引。查詢文本為 資料庫全文檢索索引bm25.match 會根據欄位的 tokenizer 自動分詞,預設命中任意一個詞即返回,並按 BM25 分數排序。

SELECT
    id,
    title,
    bm25.score(docs) AS score
FROM docs
WHERE body @@@ bm25.match('資料庫全文檢索索引')
ORDER BY bm25.score(docs) DESC
LIMIT 10;

上述 SQL 中各關鍵區段說明如下:

  • body @@@ bm25.match(...):在 body 欄位上執行 BM25 全文檢索索引。

  • bm25.score(docs):返回 BM25 相關性分數,分數越高表示越相關。

  • ORDER BY bm25.score(docs) DESC:按相關性分數降序排列,將最相關的結果排在前面。

查詢結果樣本如下。具體的 score 數值可能因版本和分詞配置略有差異:

id

title

score

2

搜尋引擎開發

...

5

中文標點測試

...

1

資料庫系統設計

...

3

向量檢索實踐

...

在實際應用中,只需將查詢文本傳遞給 bm25.match 即可執行全文檢索索引。

常見查詢寫法

AND 匹配(所有詞都必須命中)

預設情況下,bm25.match 命中任意一個詞即返回。如果要求所有詞都必須命中,可以指定 operator => 'and'

SELECT id, title, bm25.score(docs) AS score
FROM docs
WHERE body @@@ bm25.match('資料庫全文檢索索引', operator => 'and')
ORDER BY bm25.score(docs) DESC
LIMIT 10;

也可以使用簡寫操作符 &&&,效果與上述寫法相同:

SELECT id, title, bm25.score(docs) AS score
FROM docs
WHERE body &&& '資料庫全文檢索索引'
ORDER BY bm25.score(docs) DESC
LIMIT 10;

短語匹配

如果需要檢索一個完整短語(如 全文檢索索引),要求詞語相鄰且順序一致,請使用 bm25.phrase

SELECT id, title, bm25.score(docs) AS score
FROM docs
WHERE body @@@ bm25.phrase('全文檢索索引')
ORDER BY bm25.score(docs) DESC
LIMIT 10;

結構化過濾

BM25 全文檢索索引可以與普通 SQL 條件組合使用,實現分類、評分、時間等結構化過濾。

SELECT id, title, bm25.score(docs) AS score
FROM docs
WHERE body @@@ bm25.match('資料庫 檢索')
  AND category = 'tech'
  AND rating >= 4
  AND publish_at >= '2024-01-01'
ORDER BY bm25.score(docs) DESC
LIMIT 10;

多列加權查詢

當標題命中比本文命中更重要時,可以為標題欄位設定更高的權重。

SELECT id, title, bm25.score(docs) AS score
FROM docs
WHERE body @@@ bm25.multi_match(
    ARRAY['title^3', 'body'],
    query => '資料庫全文檢索索引'
)
ORDER BY bm25.score(docs) DESC
LIMIT 10;

上述樣本中,title^3 表示標題欄位的權重為本文的 3 倍;body 未指定權重時預設為 1。

說明

參與多列加權查詢的欄位必須屬於同一個 BM25 索引,且權重值必須為正數。

寫入後查詢可見度

本樣本按照"建立表 → 寫入資料 → 建立索引 → 執行查詢"的順序操作。建立索引前已經提交的資料,會在 CREATE INDEX 期間完成索引構建。因此,索引建立成功後,本樣本中的全部資料都可以直接查詢。

索引建立完成後,新執行的 INSERTUPDATE 屬於增量寫入。Nova BM25 預設採用近即時查詢模式,這部分最新資料可能需要經過短暫的幕後處理,才會出現在預設查詢結果中。

如果當前串連需要立即查詢最新增量資料,可以執行以下語句:

SET nova_bm25.query_include_mutable = on;

不再需要時恢複預設設定:

RESET nova_bm25.query_include_mutable;
說明

該設定僅影響當前資料庫連接。使用串連池時,串連可能被複用,請根據業務需要及時設定並恢複。

如果某個索引始終需要查詢最新增量資料,可以通過以下語句進行配置:

ALTER INDEX docs_bm25_idx
SET (query_skip_mutable = false);
重要

查詢最新增量資料需要額外處理尚未完成後台整理的索引資料,可能增加查詢延遲和資源消耗。

應用側參數綁定

為避免 SQL 注入風險,請勿將使用者輸入直接拼接進 SQL 字串。在 JDBC 中,建議使用 PreparedStatement 進行參數綁定:

PreparedStatement ps = conn.prepareStatement("""
    SELECT id, title, bm25.score(docs) AS score
    FROM docs
    WHERE body @@@ bm25.match(?, operator => 'or')
    ORDER BY bm25.score(docs) DESC
    LIMIT ?
""");
ps.setString(1, userQuery);
ps.setInt(2, 10);

後續步驟