執行 Spanner Graph 演算法

本文說明如何在 Spanner Graph 上執行演算法。

Spanner Graph 演算法查詢結構

Spanner Graph 演算法查詢的結構如下:

EXPORT DATA OPTIONS (export_option_list) AS
GRAPH graph_name
match_clause
call_statement algorithm_name(common_input, algorithm_specific_input)
  YIELD algorithm_specific_output
RETURN results
  • export_option_list:定義如何保存演算法查詢結果的選項。請參閱「Cloud Storage 選項」和「Spanner 選項」。

  • graph_name:圖表的名稱。

  • match_clause:選用的 MATCH 陳述式,用於定義演算法輸入元素。

  • call_statement:省略 match_clause 變數並想對整個圖表執行作業時,請使用 CALL 陳述式。如果 match_clause 變數存在,且您想對工作資料表執行作業,請使用 CALL PER() 陳述式。詳情請參閱「GQL CALL」。

  • algorithm_name:要執行的演算法名稱。如需可用演算法,請參閱 Spanner Graph 演算法。

  • common_input:所有演算法查詢通用的具名輸入參數。詳情請參閱常見演算法輸入參數。

  • algorithm_specific_input:演算法的具名輸入參數。詳情請參閱「Spanner Graph 演算法」中定義的輸入參數。

  • algorithm_specific_output:演算法呼叫的輸出內容。詳情請參閱 Spanner Graph 演算法中定義的輸出內容,以及 CALL 陳述式中的 YIELD 子句。

  • results:定義查詢結果中要傳回的內容。

查詢由 EXPORT DATA 陳述式和 GRAPH 子句組成,前者定義如何保留結果,後者則產生演算法查詢結果。

最簡單的圖表子句會識別圖表,使用 CALL 陳述式叫用會產生預先定義輸出的演算法,然後使用 RETURN 陳述式指定要從演算法輸出內容傳回的內容。

您也可以選擇使用支援的 MATCH 陳述式,選取感興趣的元素。在這種情況下,請使用 PER () 子句,將 MATCH 陳述式傳回的所有資料列分組,做為演算法的輸入內容。演算法會對選取的不重複節點和邊緣所組成的邏輯子圖進行運算。

查詢未傳回任何資料。export_option_list 變數會決定結果的保留方式。

如要進一步瞭解 Spanner Graph 演算法查詢,請參閱本文件的下列章節:

常見的演算法輸入參數

請以下列格式指定這些具名輸入參數:NAME => VALUE, ...。

名稱 值類型 必填 預設值 說明
node_labels ARRAY 否 (無) 僅支援使用 CALL 的情況。要納入演算法輸入內容的節點標籤清單。如果指定,則只會納入至少有一個相符標籤的節點。
edge_labels ARRAY 否 (無) 僅支援使用 CALL 的情況。要納入演算法輸入內容的邊緣標籤清單。如果指定,則只會納入至少有一個相符標籤的邊緣。
edge_weight_property STRING 否 (無) 包含權重的邊緣屬性名稱。如未定義,系統會為所有邊指派預設權重 1。 屬性值類型必須是數值。
machine_category STRING 否 預設 用於執行演算法的機器類別。支援的值:default、large
fallback_compute_region STRING 否 (無) 如果主區域容量不足,演算法會在備用區域執行。必須與 Spanner 執行個體的主區域位於相同管轄區 (例如,如果主區域是 us-east1,則為 us-central1)。
max_idle_time STRING 否 30 分鐘 指定演算法完成後,運算執行個體應保持運作多久,以便重複使用。格式為一連串十進位數字,每個數字都帶有單位後置字串,例如 4m、1.5h 或 1h45m。有效時間單位為 ns、us (或 µs)、ms、s、m、h。

處理演算法輸出內容

您必須先保存演算法查詢結果,才能檢查。使用 export_data_option 說明如何保留結果。您可以將結果保留在 Cloud Storage,或傳回查詢來源的 Spanner 執行個體。

將結果保留至 Cloud Storage

如要使用這個選項,請務必將 「Storage 物件管理員」(roles/storage.objectAdmin) 角色授予 Google 管理的 Spanner 服務帳戶 service-PROJECT_NUMBER@gcp-sa-spanner.。

將結果保留至 Cloud Storage 時,系統支援下列 EXPORT DATA 選項。請用下列格式指定選項:NAME=VALUE, ...。

名稱 值類型 必填 說明
uri STRING 是 匯出作業的目的地 URI,格式為 gs://bucket/path/file。如要匯出大量資料,請在 uri 中使用萬用字元,將資料匯出至多個檔案。例如:gs://bucket/path/file_*.csv。
format STRING 是 匯出資料的格式。支援的值:CSV、PARQUET、AVRO。
header BOOL 否 如果為 true,系統會為每個資料檔案的第一列輸出欄標題。預設值為 false。僅適用於 CSV。
overwrite BOOL 否 如果為 true,系統會覆寫具有相同 URI 的現有檔案。否則,如果存在具有相同 URI 的檔案,陳述式會傳回錯誤。預設值為 false。
field_delimiter STRING 否 分隔欄位的分隔符號。預設值:, (逗號)。僅適用於 CSV。
compression STRING 否 指定壓縮格式。如未指定壓縮格式,檔案將維持未壓縮狀態。
  • CSV 支援的值為 GZIP。
  • 針對 PARQUET,支援的值為:SNAPPY、GZIP、ZSTD。
  • 對於 AVRO,支援的值為:DEFLATE、SNAPPY。

RETURN 子句中的資料欄名稱會定義 Cloud Storage 輸出檔案中的資料欄名稱。

將資料匯出至一或多個檔案

Spanner Graph 查詢支援 uri 中的單一萬用字元運算子 (*)。萬用字元可以出現在檔案名稱元件中,但不能出現在 bucket 名稱、資料夾名稱或副檔名中。如果結果集很大,使用萬用字元運算子會指示 Spanner Graph 根據您提供的模式建立多個分片檔案。系統會將萬用字元運算子替換為數字,從零開始,左側補零至 12 位數。舉例來說,URI gs://my-bucket/file-*.csv 會建立 gs://my-bucket/file-000000000000.csv、gs://my-bucket/file-000000000001.csv 等類似檔案。

如果使用不含萬用字元的 uri,結果會是單一檔案,例如 gs://my-bucket/file.csv。

資料類型

匯出資料時,Spanner 圖形資料類型會依格式轉換如下:

CSV

所有資料類型都會轉換為字串表示法:

  • BOOL 值會轉換為 true 或 false。
  • BYTES 值採用 Base64 編碼。
  • TIMESTAMP 值的格式為 YYYY-MM-DD HH:MM:SS.ffffff UTC。
  • NULL 值會顯示為空字串。

您無法匯出 CSV 格式的巢狀與重複的資料。

Avro

Spanner 資料類型 Avro 資料類型
BOOL BOOLEAN
INT64 LONG
FLOAT FLOAT
DOUBLE DOUBLE
NUMERIC BYTES,邏輯類型為 DECIMAL(38,9)
STRING STRING
BYTES BYTES
TIMESTAMP LONG (自 Epoch 起算的微秒數)
NULL null

Parquet

Spanner 資料類型 Parquet 資料類型
BOOL BOOLEAN
INT64 INT64
FLOAT FLOAT
DOUBLE DOUBLE
NUMERIC DECIMAL(38,9)
STRING STRING
BYTES BYTE_ARRAY
TIMESTAMP TIMESTAMP_MICROS
NULL null

將結果保存至 Spanner

將結果保留回來源 Spanner 執行個體時,系統支援下列 EXPORT DATA 選項。請按照下列格式指定選項:NAME=VALUE, ...。

名稱 值類型 必填 說明
format STRING 是 匯出資料的格式。必須為 CLOUD_SPANNER。
table STRING 是 要寫入結果的目的地 Spanner 資料表名稱。這可以是 Spanner 執行個體中的任何資料表。
write_mode STRING 是 要使用的寫入模式。支援的值如下:
  • update_ignore_all:更新目的地資料表中的現有資料列。
  • upsert_ignore_all:在目的地資料表中插入新資料列或更新現有資料列。

無論採用哪種模式,Spanner 都會略過任何可能違反限制的記錄 (例如更新時缺少索引鍵、違反唯一索引、違反外鍵限制)。不過,如果發生非限制違規錯誤 (例如資料欄類型不符、NOT NULL 資料欄缺少值),寫入作業就會失敗。

需求條件

將演算法結果存回 Spanner 時,演算法查詢必須符合下列條件:

  • 目的地資料表必須存在。
  • 資料欄必須存在且類型相符:RETURN 子句中指定的所有資料欄名稱,都必須已存在於目的地資料表中,且資料類型相符。如有需要,請使用別名來比對目的地資料表資料欄名稱。範例:RETURN node.id AS person_id。
  • 納入所有主鍵欄:RETURN 子句必須包含目的地資料表的所有主鍵欄。

寫入語意

將結果存回 Spanner 是非交易作業。可提供資料列層級的不可部分完成作業。也就是說,系統會成功寫入同一列的所有資料欄,或完全不寫入。並遵循至少一次的語意。也就是說,一個資料列可以寫入多次。在執行期間讀取目的地資料表,可能會產生不完整的結果。

如果整體執行失敗,系統不會復原已提交的變更。如果發生第一個無法重試的錯誤,寫入程序就會失敗。發生寫入失敗時,GRAPH_OPERATION_EXECUTION_STATUS 中的 ERROR_MESSAGE 會指出失敗資料列的主鍵,以及失敗的具體原因。

系統會使用 MEDIUM 優先順序,將演算法結果寫回 Spanner Graph。

執行範例演算法查詢

本節提供 Spanner Graph 演算法查詢範例,您可以在測試執行個體上執行。如需 Spanner Graph 支援的演算法完整清單,請參閱 Spanner Graph 演算法。

事前準備

如要執行 Spanner Graph 演算法查詢範例,請先完成下列步驟:

  1. 按照「設定及查詢 Spanner Graph」一文的說明建立 Spanner Graph。
  2. 確認您具備必要權限。
  3. 選用:如果將輸出內容保留在 Spanner 中,請擴增 Spanner Graph 結構定義。

在 Account 資料表中新增名為 page_rank 的資料欄。Spanner 會將演算法結果寫入這個新資料欄。接著,重新整理圖表定義,即可將 page_rank 做為節點屬性存取。

-- Add `page_rank` as a column. Data type of this column matches the data type defined in `PageRank` output signature.
ALTER TABLE Account ADD COLUMN page_rank FLOAT64;

-- Rerun the graph definition DDL to pickup `page_rank` as a new property.
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`
  );

對完整圖表執行演算法,並使用標籤篩選器將結果保留在 Cloud Storage 中

這個範例會執行 PageRank 陳述式,根據帳戶參與的轉帳進行排名。查詢結果會以 CSV 格式保留在 Cloud Storage bucket 中,名稱為 my-bucket-name/my-output.csv。

EXPORT DATA OPTIONS (
  uri = "gs://my-bucket-name/my-output.csv",
  format = "csv"
) AS
GRAPH FinGraph
CALL PageRank(node_labels => ['Account'], edge_labels => ['Transfers']) YIELD node, score
RETURN node.id, score AS page_rank

查詢成功完成後,您應該會在 Cloud Storage 中看到一個含有兩欄 (id 和 page_rank) 的 CSV 檔案。

在 MATCH 定義的子圖上執行演算法,並將結果保留在圖表中

這個範例使用 MATCH 模式,動態比對包含所有 Account 節點和僅限金額小於 500 的 Transfer 邊緣的邏輯子圖。這個邏輯子圖是 PageRank 演算法的輸入內容。Spanner 會將演算法結果保留回 Account 資料表。

EXPORT DATA OPTIONS (
  format = "CLOUD_SPANNER",
  table = "Account",
  write_mode = 'update_ignore_all'
) AS
GRAPH FinGraph
MATCH (n:Account)
RETURN n
FULL UNION ALL
MATCH -[e:Transfers WHERE e.amount < 500]->
RETURN e
NEXT
CALL PER () PageRank() YIELD node, score
RETURN node.id, score AS page_rank

查詢成功完成後,請執行下列查詢:

GRAPH FinGraph
MATCH (n:Account)
RETURN n.id, ROUND(n.page_rank, 2) AS page_rank
ORDER BY page_rank DESC, id ASC

您應該會看到類似下方的結果:

id page_rank
20 0.49
16 0.46
7 0.05

查看演算法執行狀態

圖表演算法查詢順利完成後,會傳回零列和 Success 狀態。視輸入圖表大小和特定演算法設定而定,演算法執行作業可能需要一段時間才能完成。您可以在 SPANNER_SYS.GRAPH_OPERATION_EXECUTION_STATUS 資料表中,查看圖表演算法查詢的進度和執行狀態。這個資料表會保留 30 天的資訊。

GRAPH_OPERATION_EXECUTION_STATUS 個結構定義

資料欄名稱 類型 說明
QUERY_ID STRING 圖表演算法查詢的 ID。
QUERY_TEXT STRING 查詢陳述式文字。
START_TIMESTAMP TIMESTAMP 查詢開始執行的時間。
LAST_UPDATE_TIMESTAMP TIMESTAMP 上次更新狀態的時間。
PROGRESS FLOAT64 預估完成百分比。值介於 0 和 1 之間,其中 0 表示已開始,1 表示已完成。
STATUS STRING 目前的執行狀態。可能的值包括 PENDING、IN_PROGRESS、OK,或是錯誤狀態碼,例如 CANCELLED、DEADLINE_EXCEEDED、INVALID_ARGUMENT、FAILED_PRECONDITION、RESOURCE_EXHAUSTED、UNAVAILABLE 或 UNKNOWN。
ERROR_MESSAGE STRING 查詢執行失敗時顯示的錯誤訊息。

下列查詢範例會列出尚未成功完成的圖表查詢:

SELECT
  query_id,
  query_text,
  start_timestamp,
  last_update_timestamp,
  progress,
  status,
  error_message
FROM
  SPANNER_SYS.GRAPH_OPERATION_EXECUTION_STATUS
WHERE
  status != "OK"
ORDER BY
  start_timestamp DESC;

取消演算法執行作業

如要取消執行中的圖表演算法查詢,請從 SPANNER_SYS.GRAPH_OPERATION_EXECUTION_STATUS 資料表找出 query_id,然後對該 query_id 呼叫 cancel_query。

後續步驟