このドキュメントでは、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 が使用されている場合にのみサポートされます。アルゴリズムの入力に含めるノードラベルのリスト。指定した場合、一致するラベルが 1 つ以上あるノードのみが含まれます。 |
edge_labels |
ARRAY |
× | (なし) | CALL が使用されている場合にのみサポートされます。アルゴリズムの入力に含めるエッジラベルのリスト。指定した場合、一致するラベルが 1 つ以上あるエッジのみが含まれます。 |
edge_weight_property |
STRING |
× | (なし) | 重みを含むエッジ プロパティの名前。未定義の場合、システムはすべてのエッジにデフォルトの重み 1 を割り当てます。プロパティ値の型は数値でなければなりません。 |
machine_category |
STRING |
× | デフォルト | アルゴリズムの実行に使用するマシン カテゴリ。サポートされている値は default、large です。 |
zone |
STRING |
× | (なし) | アルゴリズムの実行が行われるゾーン。クエリが受信されたリージョンのゾーンのいずれかである必要があります。 |
max_idle_time |
STRING |
× | 30 分 | アルゴリズムの完了後に、コンピューティング インスタンスを再利用のためにアクティブな状態に保つ期間を指定します。形式は、10 進数のシーケンスで、それぞれに単位接尾辞が付いています(例: 4m、1.5h、1h45m)。有効な時間単位は、ns、us(または µs)、ms、s、m、h です。 |
アルゴリズムの出力を処理する
アルゴリズムのクエリ結果を検査するには、その結果を永続化する必要があります。export_data_option を使用して、結果を永続化する方法を記述します。結果は、Cloud Storage に永続化することも、クエリの送信元と同じ Spanner インスタンスに永続化することもできます。
結果を Cloud Storage に保持する
このオプションを使用するには、Google マネージド Spanner サービス アカウント
service-PROJECT_NUMBER@gcp-sa-spanner.iam.gserviceaccount.com に Storage オブジェクト管理者(roles/storage.objectAdmin)ロールが付与されていることを確認します。
結果を 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 出力ファイルの列名を定義します。
データを 1 つ以上のファイルにエクスポートする
Spanner Graph クエリは、uri で 1 つのワイルドカード演算子(*)をサポートしています。ワイルドカードはファイル名コンポーネントで使用できますが、バケット名、フォルダ名、ファイル拡張子では使用できません。ワイルドカード演算子を使用すると、Spanner Graph は、結果セットが大きい場合に、指定したパターンに基づいて複数の分割ファイルを作成します。ワイルドカード演算子は、左側に 0 が埋められた 12 桁の数値(0 から始まるシーケンス番号)に置き換えられます。たとえば、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 |
論理型 DECIMAL(38,9) の BYTES |
STRING |
STRING |
BYTES |
BYTES |
TIMESTAMP |
LONG(エポックからのマイクロ秒数) |
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 に永続化する操作は、トランザクション処理ではありません。行レベルの原子性が提供されます。つまり、システムは同じ行のすべての列を正常に書き込むか、どの列も書き込みません。これは、at-least-once セマンティクスに従います。つまり、行は複数回書き込むことができます。実行中に宛先テーブルから読み取ると、結果が不完全になる可能性があります。
全体的な実行が失敗した場合、システムはすでに commit された変更をロールバックしません。書き込みプロセスは、最初のリトライ不可エラーで失敗します。書き込みエラーが発生すると、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 を実行して、参加している Transactions に基づいて Account をランク付けし、結果を 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 に 2 つの列(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;
アルゴリズムの実行をキャンセルする
実行中のグラフ アルゴリズム クエリをキャンセルするには、SPANNER_SYS.GRAPH_OPERATION_EXECUTION_STATUS テーブルから query_id を見つけて、その query_id に対して cancel_query を呼び出します。