本頁說明如何在 Spanner 中執行全文和向量混合搜尋。混合型搜尋結合了關鍵字比對 (全文搜尋,FTS) 的精確度,以及語意比對 (向量搜尋) 的召回率,可產生高度相關的搜尋結果。
Spanner 支援下列混合搜尋模式,主要分為三類:
| 類別 | 說明 | 主要目標 |
| Fusion | Fusion 會使用關鍵字和向量搜尋功能,獨立擷取文件並排名,然後合併 (融合) 結果。 | 結合多個評分信號,盡可能提高召回率和關聯性。 |
| 已篩選 | 關鍵字可篩選或縮小搜尋範圍。 | 確保關鍵字比對是必要條件,同時運用語意相關性。 |
| 機器學習重新排序 | 機器學習模型會先產生初步的候選人名單,然後再進行精確的排序。 | 針對少量最終結果,盡可能提高精確度。 |
融合搜尋
融合搜尋是指在相同的資料集上,分別執行全文搜尋和向量搜尋。然後合併結果,建立單一、統一且高度相關的排名清單。
雖然您可以在用戶端執行獨立查詢,但 Spanner 中的混合搜尋具有下列優點:
- 在伺服器上管理並行要求和合併結果,簡化應用程式邏輯。
- 避免將可能很大的中繼結果集傳輸至用戶端。
您可以使用 SQL 在 Spanner 中建立融合方法。本節提供倒數排名融合和相對分數融合的範例。不過,我們建議評估不同的融合策略,找出最符合應用程式需求的策略。
以排名為準的融合
如果不同擷取方法 (例如 FTS 分數和向量距離) 的關聯性分數難以比較或正規化 (因為是在不同空間中測量),請使用以排名為準的融合方式。這個方法會使用每個檢索器中每份文件的排名位置,產生最終分數和排名。
倒數排序融合 (RRF) 是以排序為基礎的融合函式。文件的 RRF 分數是多個檢索器排名的倒數總和,計算方式如下:
\[ score\ (d\epsilon D)\ =\ \sum\limits_{r\epsilon R}^{}(1\ /\ (\ 𝑘\ +\ ran{k}_{r}\ (𝑑)\ )\ )\ \]
其中:
- d 是文件。
- R 是檢索器集 (FTS 和向量搜尋)。
- k 是常數 (通常設為 60),用於調和排名非常高的文件影響力。
- w 是檢索器 r 中文件的排名。
在 Spanner 查詢中實作 RRF
向量指標 (例如 APPROX_DOT_PRODUCT) 和文字搜尋分數 (例如 SCORE_NGRAMS) 的運作方式不相容。為解決這個問題,下列範例會實作 RRF,根據排名位置而非原始分數來正規化資料。
查詢會使用 UNNEST(ARRAY(...) WITH OFFSET) 為每種方法的前 100 名候選人指派排名。接著,系統會使用這些排名的倒數計算標準化分數,並匯總結果,傳回前五個相符項目。
SELECT SUM(1 / (60 + rank)) AS rrf_score, key
FROM (
(
SELECT rank, x AS key
FROM UNNEST(ARRAY(
SELECT key
FROM hybrid_search
WHERE embedding IS NOT NULL
ORDER BY APPROX_DOT_PRODUCT(@vector, embedding,
OPTIONS => JSON '{"num_leaves_to_search": 50}') DESC
LIMIT 100)) AS x WITH OFFSET AS rank
)
UNION ALL
(
SELECT rank, x AS key
FROM UNNEST(ARRAY(
SELECT key
FROM hybrid_search
WHERE SEARCH_NGRAMS(text_tokens_ngrams, 'foo')
ORDER BY SCORE_NGRAMS(text_tokens_ngrams, 'foo') DESC
LIMIT 100)) AS x WITH OFFSET AS rank
)
)
GROUP BY key
ORDER BY rrf_score DESC
LIMIT 5;
以分數為依據的融合
當不同方法提供的關聯性分數可比較或可正規化時,基於分數的融合方式就相當有效,這可能有助於更精確地排名,並納入每種方法的實際關聯性權重。
相對分數融合 (RSF) 是一種以分數為基礎的方法,可將不同方法的分數正規化,以各方法中的最高和最低分數為基準,通常會使用 MIN() 和 MAX() 函式。由一組檢索器擷取的文件的 RSF 分數計算方式如下:
\[ score(d\epsilon D)\ =\ \sum\limits_{r\epsilon R}^{}({w}_{r}*(scor{e}_{r}(d)\ -\ mi{n}_{r})\ /\ (ma{x}_{r\ }-mi{n}_{r})\ ) \]
其中:
- d 是文件。
- R 是檢索器集 (FTS 和向量搜尋)。
- w 是指派給特定檢索器的權重。
在 Spanner 查詢中實作 RSF
如要實作 RSF,您必須將向量和 FTS 的分數正規化為通用比例。以下範例會計算個別 WITH 子句中的最低和最高分數,以得出標準化因數。然後使用 FULL OUTER JOIN 合併結果,加總近似近鄰 (ANN) 搜尋 (從 cosine_distance 轉換) 和 FTS 的標準化分數。
WITH ann AS (
SELECT key, APPROX_COSINE_DISTANCE(@vector, embedding,
OPTIONS => JSON '{"num_leaves_to_search": 50}') AS cosine_distance,
FROM hybrid_search
WHERE embedding IS NOT NULL
ORDER BY cosine_distance
LIMIT 100
),
fts AS (
SELECT key, SCORE_NGRAMS(text_tokens_ngrams, 'Green') AS score,
FROM hybrid_search
WHERE SEARCH_NGRAMS(text_tokens_ngrams, 'Green')
ORDER BY score DESC
LIMIT 100
),
ann_min AS (
SELECT MIN(1 - cosine_distance) AS min
FROM ann
),
ann_max AS (
SELECT MAX(1 - cosine_distance) AS max
FROM ann
),
fts_min AS (
SELECT MIN(score) AS min
FROM fts
),
fts_max AS (
SELECT MAX(score) AS max
FROM fts
)
SELECT IFNULL(ann.key, fts.key),
IFNULL(((1 - ann.cosine_distance) - ann_min.min) /
(ann_max.max - ann_min.min), 0) +
IFNULL((fts.score - fts_min.min) /
(fts_max.max - fts_min.min), 0) AS score
FROM ann
FULL OUTER JOIN fts
ON ann.key = fts.key
CROSS JOIN ann_min
CROSS JOIN ann_max
CROSS JOIN fts_min
CROSS JOIN fts_max
ORDER BY score DESC
LIMIT 5;
篩選搜尋結果
篩選搜尋會使用 FTS 建立篩選條件,減少要納入 K 近鄰 (KNN) 向量搜尋的文件集。您可以選擇使用預先排序,限制結果集的大小。
在 Spanner 查詢中實作篩選搜尋
本節的搜尋範例會執行下列步驟,將向量搜尋空間縮小至與關鍵字相符的資料子集:
- 使用
SEARCH (text_tokens, 'Green')找出text_tokens資料欄含有Green文字的資料列。系統會根據搜尋索引定義的重新排序順序,傳回前 1000 列。 - 使用向量函式
DOT_PRODUCT(@vector, embedding)計算查詢向量 (@vector) 與儲存的文件向量 (嵌入) 之間的相似度。然後排序結果,並傳回最終的前 10 個相符項目。
SELECT key
FROM (
SELECT key, embedding
FROM hybrid_search
WHERE SEARCH (text_tokens, 'Green')
ORDER BY presort
LIMIT 1000)
ORDER BY DOT_PRODUCT(@vector, embedding) DESC
LIMIT 10;
機器學習重新排序
以機器學習為基礎的重新排序方法需要大量運算,但準確度極高。 這項功能會將機器學習模型套用至 FTS、向量搜尋或兩者結合縮減的小型候選項目集。如要進一步瞭解 Spanner Vertex AI 整合功能,請參閱 Spanner Vertex AI 整合功能總覽。
您可以透過 Spanner ML.PREDICT 函式,整合機器學習重排功能和已部署的 Vertex AI 模型。
導入以機器學習為基礎的重新排序功能
- 將重排序模型 (例如來自 HuggingFace) 部署至 Vertex AI 端點。
建立指向 Vertex AI 端點的 Spanner
MODEL物件。舉例來說,在下列Reranker模型範例中:text ARRAY<string(max)>是文件。text_pair ARRAY<string(max)>是範例中的查詢文字。score是機器學習模型為輸入文字配對指派的關聯分數。
CREATE MODEL Reranker INPUT (text ARRAY<string(max)>, text_pair ARRAY<string(max)>) OUTPUT (score FLOAT32) REMOTE OPTIONS ( endpoint = '...' );使用子查詢擷取初始候選項目 (例如 ANN 搜尋的前 100 個結果),並將這些項目傳遞至
ML.PREDICT。函式會傳回最終排序的新分數資料欄。SELECT key FROM ML.PREDICT( MODEL Reranker, ( SELECT key, text, "gift for 8-year-old" AS text_pair FROM hybrid_search WHERE embedding IS NOT NULL ORDER BY APPROX_DOT_PRODUCT(@vector, embedding, options=>JSON '{"num_leaves_to_search": 50}') DESC LIMIT 100) ) ORDER BY score DESC LIMIT 3;