本文說明如何在 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 |
否 | 指定壓縮格式。如未指定壓縮格式,檔案將維持未壓縮狀態。
|
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 |
是 | 要使用的寫入模式。支援的值如下:
無論採用哪種模式,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 演算法查詢範例,請先完成下列步驟:
- 按照「設定及查詢 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 陳述式,根據帳戶參與的轉帳進行排名。查詢結果會以 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。