本頁說明如何在 Spanner 中執行向量相似度搜尋,方法是使用餘弦距離、歐氏距離和點積向量函式,找出 K 個最鄰近的項目。這項資訊適用於 GoogleSQL 方言資料庫和 PostgreSQL 方言資料庫。閱讀本頁面之前,請務必瞭解下列概念:
- 歐氏距離:測量兩個向量之間的最短距離。
- 餘弦距離: 測量兩個向量間的角度餘弦值。
- 內積:計算角度的餘弦值,並乘以對應向量大小的乘積。如果您知道資料集中的所有向量嵌入內容都已正規化,則可以使用
DOT_PRODUCT()
做為距離函式。 - K 最鄰近 (KNN): 一種監督式機器學習演算法,用於解決分類或迴歸問題。
您可以使用向量距離函式執行 K 近鄰 (KNN) 向量搜尋,用於相似度搜尋或檢索增強生成等用途。Spanner 支援 COSINE_DISTANCE()
、EUCLIDEAN_DISTANCE()
和 DOT_PRODUCT()
函式,這些函式可對向量嵌入內容執行作業,讓您找出輸入嵌入內容的 KNN。
舉例來說,將作業 Spanner 資料產生並儲存為向量嵌入後,您就可以在查詢中提供這些向量嵌入做為輸入參數,在 N 維空間中尋找最接近的向量,搜尋語意相似或相關的項目。
這三個距離函式都會採用 vector1
和 vector2
引數,這兩個引數屬於 array<>
類型,且必須包含相同維度,長度也必須相同。如要進一步瞭解這些函式,請參閱:
COSINE_DISTANCE()
in GoogleSQLEUCLIDEAN_DISTANCE()
in GoogleSQLDOT_PRODUCT()
in GoogleSQL- PostgreSQL 中的數學函式
(
spanner.cosine_distance()
、spanner.euclidean_distance()
和spanner.dot_product()
) - 選擇向量距離函式,測量向量嵌入的相似度。
範例
下列範例會說明 KNN 搜尋、對分割資料進行 KNN 搜尋,以及搭配 KNN 使用次要索引。
所有範例都使用 EUCLIDEAN_DISTANCE()
。你也可以使用 COSINE_DISTANCE()
。此外,如果資料集中的所有向量嵌入都經過正規化,您可以使用 DOT_PRODUCT()
做為距離函式。
範例 1:KNN 搜尋
假設 Documents
資料表含有從 DocContents
位元組資料欄預先計算的文字嵌入 DocEmbedding
資料欄。
GoogleSQL
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocId INT64 NOT NULL,
Author STRING(1024),
DocContents BYTES(MAX),
DocEmbedding ARRAY<FLOAT32>
) PRIMARY KEY (UserId, DocId);
PostgreSQL
CREATE TABLE Documents (
UserId bigint NOT NULL,
DocId bigint NOT NULL,
Author varchar(1024),
DocContents bytea,
DocEmbedding float4[],
PRIMARY KEY (UserId, DocId)
);
假設「棒球,但不是職業棒球」的輸入內容嵌入是陣列 [0.3, 0.3, 0.7, 0.7]
,您可以使用下列查詢,找出最接近的前五個相符文件:
GoogleSQL
SELECT DocId, DocEmbedding FROM Documents
ORDER BY EUCLIDEAN_DISTANCE(DocEmbedding,
ARRAY<FLOAT32>[0.3, 0.3, 0.7, 0.8])
LIMIT 5;
PostgreSQL
SELECT DocId, DocEmbedding FROM Documents
ORDER BY spanner.euclidean_distance(DocEmbedding,
'{0.3, 0.3, 0.7, 0.8}'::float4[])
LIMIT 5;
這個範例的預期結果如下:
Documents
+---------------------------+-----------------+
| DocId | DocEmbedding |
+---------------------------+-----------------+
| 24 | [8, ...] |
+---------------------------+-----------------+
| 25 | [6, ...] |
+---------------------------+-----------------+
| 26 | [3.2, ...] |
+---------------------------+-----------------+
| 27 | [38, ...] |
+---------------------------+-----------------+
| 14229 | [1.6, ...] |
+---------------------------+-----------------+
例 2:對分區資料執行 KNN 搜尋
您可以修改上一個範例中的查詢,在 WHERE
子句中新增條件,將向量搜尋限制為資料子集。這項功能常見的應用是搜尋分區資料,例如屬於特定 UserId
的資料列。
GoogleSQL
SELECT UserId, DocId, DocEmbedding FROM Documents
WHERE UserId=18
ORDER BY EUCLIDEAN_DISTANCE(DocEmbedding,
ARRAY<FLOAT32>[0.3, 0.3, 0.7, 0.8])
LIMIT 5;
PostgreSQL
SELECT UserId, DocId, DocEmbedding FROM Documents
WHERE UserId=18
ORDER BY spanner.euclidean_distance(DocEmbedding,
'{0.3, 0.3, 0.7, 0.8}'::float4[])
LIMIT 5;
這個範例的預期結果如下:
Documents
+-----------+-----------------+-----------------+
| UserId | DocId | DocEmbedding |
+-----------+-----------------+-----------------+
| 18 | 234 | [12, ...] |
+-----------+-----------------+-----------------+
| 18 | 12 | [1.6, ...] |
+-----------+-----------------+-----------------+
| 18 | 321 | [22, ...] |
+-----------+-----------------+-----------------+
| 18 | 432 | [3, ...] |
+-----------+-----------------+-----------------+
範例 3:透過次要索引範圍進行 KNN 搜尋
如果您使用的 WHERE
子句篩選器不屬於資料表的主鍵,則可建立次要索引,透過僅限索引掃描加快作業速度。
GoogleSQL
CREATE INDEX DocsByAuthor
ON Documents(Author)
STORING (DocEmbedding);
SELECT Author, DocId, DocEmbedding FROM Documents
WHERE Author="Mark Twain"
ORDER BY EUCLIDEAN_DISTANCE(DocEmbedding,
<embeddings for "book about the time traveling American">)
LIMIT 5;
PostgreSQL
CREATE INDEX DocsByAuthor
ON Documents(Author)
INCLUDE (DocEmbedding);
SELECT Author, DocId, DocEmbedding FROM Documents
WHERE Author="Mark Twain"
ORDER BY spanner.euclidean_distance(DocEmbedding,
<embeddings for "that book about the time traveling American">)
LIMIT 5;
這個範例的預期結果如下:
Documents
+------------+-----------------+-----------------+
| Author | DocId | DocEmbedding |
+------------+-----------------+-----------------+
| Mark Twain | 234 | [12, ...] |
+------------+-----------------+-----------------+
| Mark Twain | 12 | [1.6, ...] |
+------------+-----------------+-----------------+
| Mark Twain | 321 | [22, ...] |
+------------+-----------------+-----------------+
| Mark Twain | 432 | [3, ...] |
+------------+-----------------+-----------------+
| Mark Twain | 375 | [9, ...] |
+------------+-----------------+-----------------+
後續步驟
進一步瞭解 GoogleSQL
COSINE_DISTANCE()
、EUCLIDEAN_DISTANCE()
、DOT_PRODUCT()
函式。進一步瞭解 PostgreSQL
spanner.cosine_distance()
、spanner.euclidean_distance()
、spanner.dot_product()
函式。進一步瞭解如何選擇向量距離函式,測量向量嵌入相似度。