搭配使用向量搜尋和 Spanner Graph

本頁說明如何在 Spanner Graph 中使用向量搜尋功能,找出 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 Graph」中的步驟,完成下列操作:

  1. 建立執行個體
  2. 使用 Spanner Graph 結構定義建立資料庫
  3. 插入基本圖表資料

插入必要的圖形資料後,請對資料庫進行下列更新。

在圖形資料庫中插入其他向量資料

如要對圖形資料庫進行必要更新,請按照下列步驟操作:

  1. Account 輸入表格中新增 nick_name_embeddings 資料欄。

    ALTER TABLE Account
    ADD COLUMN nick_name_embeddings ARRAY<FLOAT32>(vector_length=>4);
    
  2. 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;
    
  3. nick_name 欄中的文字建立嵌入項目,並填入新的 nick_name_embeddings 欄。

    如要為 Spanner Graph 中的作業資料生成 Gemini Enterprise Agent Platform 嵌入內容,請參閱「取得 Agent Platform 文字嵌入內容」。

    為方便說明,我們的範例使用人工低維度向量值。

    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;
    
  4. AccountTransferAccount 輸入表格中新增兩個資料欄:notesnotes_embeddings

    ALTER TABLE AccountTransferAccount
    ADD COLUMN notes STRING(MAX);
    ALTER TABLE AccountTransferAccount
    ADD COLUMN notes_embeddings ARRAY<FLOAT32>(vector_length=>4);
    
  5. notes 欄中的文字建立嵌入項目,並填入 notes_embeddings 欄。

    如要為 Spanner Graph 中的作業資料生成 Agent Platform 嵌入內容,請參閱「取得 Agent Platform 文字嵌入內容」。

    為方便說明,我們的範例使用人工低維度向量值。

    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;
    
  6. AccountAccountTransferAccount 輸入資料表新增資料欄後,請使用下列陳述式更新屬性圖形定義。詳情請參閱更新現有節點或邊緣定義

    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。在下列範例中,結果會顯示「休閒旅遊和度假帳戶」的前兩個 K 近鄰,以 [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。在下列範例中,結果會顯示「food expenses」(食物支出) 的前兩個 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 參數設為 COSINEDOT_PRODUCTEUCLIDEAN,選擇最適合用途的距離指標。詳情請參閱「VECTOR INDEX 陳述式」。

在下列範例中,您會在 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 為旅行存錢

後續步驟