本頁說明如何在 Spanner 圖中使用向量搜尋功能,找出 K 近鄰 (KNN) 和近似近鄰 (ANN)。您可以使用向量距離函式執行 KNN 和 ANN 向量搜尋,用於相似度搜尋或檢索增強生成的生成式 AI 應用程式等用途。
Spanner Graph 支援下列距離函式,可執行 KNN 向量相似度搜尋:
COSINE_DISTANCE()
:測量兩個向量之間的最短距離。EUCLIDEAN_DISTANCE()
:測量兩個向量夾角的餘弦值。DOT_PRODUCT()
:計算角的餘弦乘以對應向量大小的積。如果您知道資料集中的所有向量嵌入值都已標準化,就可以使用DOT_PRODUCT()
做為距離函式。
如需更多資訊,請參閱「在 Spanner 中執行向量相似度搜尋,方法是找出 K 個最近鄰」。
Spanner Graph 也支援下列近似距離函式,用於執行 ANN 向量相似度搜尋:
APPROX_COSINE_DISTANCE
:測量兩個向量之間的近似最短距離。APPROX_EUCLIDEAN_DISTANCE
:測量兩個向量之間角度的近似餘弦值。APPROX_DOT_PRODUCT
:計算角度的近似餘弦值,再乘上對應向量大小的積。如果您知道資料集中的所有向量嵌入值都已標準化,則可以使用DOT_PRODUCT()
做為距離函式。
詳情請參閱「找出近似最近鄰、建立向量索引,以及查詢向量嵌入」。
事前準備
如要執行本文中的範例,您必須先按照「設定及查詢 Spanner 圖」中的步驟執行以下操作:
插入必要的圖表資料後,請對資料庫進行下列更新。
在圖形資料庫中插入其他向量資料
如要對圖形資料庫進行必要更新,請執行下列操作:
在
Account
輸入表格中新增資料欄nick_name_embeddings
。ALTER TABLE Account ADD COLUMN nick_name_embeddings ARRAY<FLOAT32>(vector_length=>4);
在
nick_name
欄中新增資料。UPDATE Account SET nick_name = "Fund for a refreshing tropical vacation" WHERE id = 7; UPDATE Account SET nick_name = "Fund for a rainy day!" WHERE id = 16; UPDATE Account SET nick_name = "Saving up for travel" WHERE id = 20;
為
nick_name
欄中的文字建立嵌入項目,然後將這些項目填入新的nick_name_embeddings
欄。如要在 Spanner Graph 中為營運資料產生 Vertex AI 嵌入資料,請參閱「取得 Vertex AI 文字嵌入資料」。
為方便說明,我們在範例中使用人工的低維向量值。
UPDATE Account SET nick_name_embeddings = ARRAY<FLOAT32>[0.3, 0.5, 0.8, 0.7] WHERE id = 7; UPDATE Account SET nick_name_embeddings = ARRAY<FLOAT32>[0.4, 0.9, 0.7, 0.1] WHERE id = 16; UPDATE Account SET nick_name_embeddings = ARRAY<FLOAT32>[0.2, 0.5, 0.6, 0.6] WHERE id = 20;
在
AccountTransferAccount
輸入表格中新增兩個資料欄:notes
和notes_embeddings
。ALTER TABLE AccountTransferAccount ADD COLUMN notes STRING(MAX); ALTER TABLE AccountTransferAccount ADD COLUMN notes_embeddings ARRAY<FLOAT32>(vector_length=>4);
為
notes
欄中的文字建立嵌入項目,並將這些項目填入notes_embeddings
欄。如要在 Spanner Graph 中為營運資料產生 Vertex AI 嵌入資料,請參閱「取得 Vertex AI 文字嵌入資料」。
為方便說明,我們在範例中使用人工的低維向量值。
UPDATE AccountTransferAccount SET notes = "for shared cost of dinner", notes_embeddings = ARRAY<FLOAT32>[0.3, 0.5, 0.8, 0.7] WHERE id = 16 AND to_id = 20; UPDATE AccountTransferAccount SET notes = "fees for tuition", notes_embeddings = ARRAY<FLOAT32>[0.1, 0.9, 0.1, 0.7] WHERE id = 20 AND to_id = 7; UPDATE AccountTransferAccount SET notes = 'loved the lunch', notes_embeddings = ARRAY<FLOAT32>[0.4, 0.5, 0.7, 0.9] WHERE id = 20 AND to_id = 16;
在
Account
和AccountTransferAccount
輸入表中新增資料欄後,請使用下列陳述式更新屬性圖表定義。詳情請參閱「更新現有的節點或邊定義」。CREATE OR REPLACE PROPERTY GRAPH FinGraph NODE TABLES (Account, Person) EDGE TABLES ( PersonOwnAccount SOURCE KEY (id) REFERENCES Person (id) DESTINATION KEY (account_id) REFERENCES Account (id) LABEL Owns, AccountTransferAccount SOURCE KEY (id) REFERENCES Account (id) DESTINATION KEY (to_id) REFERENCES Account (id) LABEL Transfers );
尋找 K 個最近鄰
在以下範例中,使用 EUCLIDEAN_DISTANCE()
函式對圖形資料庫的節點和邊執行 KNN 向量搜尋。
對圖表節點執行 KNN 向量搜尋
您可以對 Account
節點的 nick_name_embeddings
屬性執行 KNN 向量搜尋。這個 KNN 向量搜尋會傳回帳戶擁有者的 name
和帳戶的 nick_name
。在以下範例中,結果會顯示休閒旅遊和度假帳戶的前兩個最近鄰點,以 [0.2, 0.4, 0.9, 0.6]
向量嵌入表示。
GRAPH FinGraph
MATCH (p:Person)-[:Owns]->(a:Account)
RETURN p.name, a.nick_name
ORDER BY EUCLIDEAN_DISTANCE(a.nick_name_embeddings,
-- An illustrative embedding for 'accounts for leisure travel and vacation'
ARRAY<FLOAT32>[0.2, 0.4, 0.9, 0.6])
LIMIT 2;
結果
名稱 | nick_name |
---|---|
Alex | 儲蓄資金,享受清新的熱帶假期 |
Dana | 存錢出國旅遊 |
針對圖形邊緣執行 KNN 向量搜尋
您可以對 Owns
邊緣的 notes_embeddings
屬性執行 KNN 向量搜尋。這個 KNN 向量搜尋會傳回帳戶擁有者的 name
和轉移的 notes
。在以下範例中,結果會顯示「餐飲費」的兩個最相近的 K 個鄰居,以 [0.2, 0.4, 0.9, 0.6]
向量嵌入表示。
GRAPH FinGraph
MATCH (p:Person)-[:Owns]->(:Account)-[t:Transfers]->(:Account)
WHERE t.notes_embeddings IS NOT NULL
RETURN p.name, t.notes
ORDER BY EUCLIDEAN_DISTANCE(t.notes_embeddings,
-- An illustrative vector embedding for 'food expenses'
ARRAY<FLOAT32>[0.2, 0.4, 0.9, 0.6])
LIMIT 2;
結果
名稱 | 附註 |
---|---|
Lee | 晚餐分攤費用 |
Dana | 午餐很棒 |
建立向量索引並找出近似最鄰近項目
如要執行 ANN 搜尋,您必須建立 專用向量索引,讓 Spanner Graph 用於加快向量搜尋速度。向量索引必須使用特定距離指標。您可以將 distance_type
參數設為 COSINE
、DOT_PRODUCT
或 EUCLIDEAN
等其中一個,選擇最適合您用途的距離指標。詳情請參閱「向量索引語句」。
在下列範例中,您會使用 Account
輸入資料表的 nick_name_embedding
欄位,以歐氏距離類型建立向量索引:
CREATE VECTOR INDEX NickNameEmbeddingIndex
ON Account(nick_name_embeddings)
WHERE nick_name_embeddings IS NOT NULL
OPTIONS (distance_type = 'EUCLIDEAN', tree_depth = 2, num_leaves = 1000);
對圖形節點執行 ANN 向量搜尋
建立向量索引後,您就可以針對 Account
節點的 nick_name
屬性執行 ANN 向量搜尋。ANN 向量搜尋會傳回帳戶擁有者的 name
和帳戶的 nick_name
。在以下範例中,結果會顯示休閒旅遊和度假帳戶的前兩個近似近鄰,由 [0.2, 0.4, 0.9, 0.6]
向量嵌入表示。
圖表提示會強制查詢最佳化工具在查詢執行計畫中使用指定的向量索引。
GRAPH FinGraph
MATCH (@{FORCE_INDEX=NickNameEmbeddingIndex} a:Account)
WHERE a.nick_name_embeddings IS NOT NULL
RETURN a, APPROX_EUCLIDEAN_DISTANCE(a.nick_name_embeddings,
-- An illustrative embedding for 'accounts for leisure travel and vacation'
ARRAY<FLOAT32>[0.2, 0.4, 0.9, 0.6],
options => JSON '{"num_leaves_to_search": 10}') AS distance
ORDER BY distance
LIMIT 2
NEXT
MATCH (p:Person)-[:Owns]->(a)
RETURN p.name, a.nick_name;
結果
名稱 | nick_name |
---|---|
Alex | 儲蓄資金,享受清新的熱帶假期 |
Dana | 存錢出國旅遊 |
後續步驟
- 找出 K 個最近鄰,在 Spanner 中執行向量相似度搜尋。
- 找出近似最近鄰、建立向量索引,以及查詢向量嵌入。
- 取得 Vertex AI 文字嵌入資料
- 進一步瞭解 Spanner 圖表查詢。
- 瞭解調整查詢的最佳做法。