本文說明如何在 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 |
zone |
STRING |
否 | (無) | 演算法執行的區域。必須是接收查詢的區域中的其中一個可用區。 |
max_idle_time |
STRING |
否 | 30m | 指定演算法完成後,運算執行個體應保持運作多久,以便重複使用。格式為一連串小數,每個小數都加上單位後置字串,例如 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.iam.gserviceaccount.com。
將結果保存到 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 |
否 | 指定壓縮格式。如未指定壓縮格式,檔案會維持未壓縮狀態。
|
RETURN 子句中的資料欄名稱會定義 Cloud Storage 輸出檔案中的資料欄名稱。
將資料匯出為一或多個檔案
Spanner Graph 查詢支援在 uri 中使用單一萬用字元運算子 (*)。萬用字元可以出現在檔案名稱元件中,但不得出現在值區名稱、資料夾名稱或副檔名中。如果結果集很大,使用萬用字元運算子就會指示 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 |
是 | 要使用的寫入模式。支援的值如下:
在這兩種模式中,如果記錄會導致違反限制 (例如更新時缺少鍵、違反唯一索引或外鍵限制),Spanner 會略過該記錄。不過,如果發生非限制條件違規的錯誤 (例如資料欄類型不符、NOT NULL 資料欄缺少值),寫入作業就會失敗。 |
需求條件
將演算法結果存回 Spanner 時,演算法查詢必須符合下列條件:
- 目的地資料表必須存在。
- 資料欄必須存在且類型相符:
RETURN子句中指定的所有資料欄名稱,都必須已存在於目的地資料表中,且資料類型相符。如有需要,請使用別名來比對目的地資料表欄名稱。範例:RETURN node.id AS person_id。 - 納入所有主鍵欄:
RETURN子句必須包含目的地資料表的所有主鍵欄。
撰寫元件資訊
將結果存回 Spanner 是非交易作業。可提供資料列層級的不可分割性。也就是說,系統會成功寫入同一列的所有資料欄,或完全不寫入。這項作業遵循「至少傳送一次」語意。也就是說,資料列可以多次寫入。執行作業期間,如果從目的地資料表讀取資料,可能會產生不完整的結果。
如果整體執行作業失敗,系統不會復原已提交的變更。如果發生第一個無法重試的錯誤,寫入程序就會失敗。發生寫入失敗時,GRAPH_OPERATION_EXECUTION_STATUS 中的 ERROR_MESSAGE 會指出失敗的資料列主鍵,以及失敗的具體原因。
系統會使用 MEDIUM priority 將演算法結果寫回 Spanner Graph。
執行範例演算法查詢
本節顯示您可在測試執行個體上執行的 Spanner Graph 演算法查詢範例。如需 Spanner Graph 支援的演算法完整清單,請參閱 Spanner Graph 演算法。
事前準備
如要執行 Spanner Graph 演算法查詢範例,請先完成下列步驟:
- 按照「設定及查詢 Spanner Graph」一文的說明,建立 Spanner Graph。
- 請確認您具備必要權限。
- 選用:如果將輸出內容保留在 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,根據 Account 參與的 Transactions 排名,並以 CSV 格式將結果儲存至 Cloud Storage,如「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 |
FLOAT |
預估完成百分比。值介於 0 和 1 之間,其中 0 表示已開始,1 表示已完成。 |
STATUS |
STRING |
目前的執行狀態。可能的值為 PENDING、IN_PROGRESS、OK、CANCELLED、DEADLINE_EXCEEDED、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;
取消演算法執行作業
如要取消進行中的圖表演算法查詢,請在 query_id 的 SPANNER_SYS.GRAPH_OPERATION_EXECUTION_STATUS 表格中找出 query_id,然後呼叫該 query_id 的 cancel_query。