パスを操作する

このページでは、Spanner Graph でグラフパスを操作する方法について説明します。

グラフ データベースでは、グラフパス データ型はエッジと交互に配置された一連のノードを表し、これらのノードとエッジがどのように関連しているかを示します。パスデータ型の詳細については、グラフパスの種類をご覧ください。

Spanner Graph Language(GQL)を使用すると、グラフパスを構築してクエリを実行できます。このドキュメントの例では、Spanner Graph を設定してクエリを実行するページと同じ Spanner Graph スキーマを使用します。

グラフパスを作成する

グラフパスを作成するには、グラフパターンでパス変数を作成するか、PATH 関数を使用します。

パス変数を使用してグラフパスを作成することをおすすめします。パス変数を作成する形式は次のとおりです。

MATCH p = PATH_PATTERN

詳細については、グラフパターンをご覧ください。

次の例では、FinGraph 内のアカウント間の送金のパターンを検索します。

GRAPH FinGraph
MATCH p = (src:Account {id: 16})-[t1:Transfers]->(mid:Account)-[t2:Transfers]->
  (dst:Account {id: 7})
RETURN TO_JSON(p) AS full_path;

結果

full_path
[{"identifier": ..., "properties": {"id": 16, ...}, ...}, {"identifier": ..., "properties": {"amount": 300.0, ...}, ...}, ...]

この結果は、クエリがデータベースで Account -> Transfers -> Account パターンを見つけたことを示しています。

グラフパスをクエリする

次のパス固有の関数を使用して、グラフパスをクエリできます。Spanner Graph クエリの一般的な情報については、クエリの概要をご覧ください。

EDGES

EDGES 関数は、グラフパス内のすべてのエッジを返します。セマンティクスの詳細については、EDGES をご覧ください。

このクエリは、中間アカウントを経由する 2 つのアカウント間のパスを見つけます。パス内の 2 番目の Transfers エッジの量を返します。これは、srcmid の間、または middst の間のいずれかです。

GRAPH FinGraph
MATCH p = (src:Account {id: 7})-[t1:Transfers]->{1,3}(mid:Account)-[t2:Transfers]->
  {1,3}(dst:Account {id: 16})
LET second_edge = EDGES(p)[1]
RETURN DISTINCT src.id AS src, dst.id AS dst, second_edge.amount AS second_edge_amount;

結果

src dst second_edge_amount
7 16 300

NODES

NODES 関数は、グラフパス内のすべてのノードを返します。セマンティクスの詳細については、NODES をご覧ください。

このクエリは、2 つの転送のグラフパスを見つけて、パスを表す JSON リストを返します。

GRAPH FinGraph
MATCH p = (src:Account)-[t1:Transfers]->(mid:Account)-[t2:Transfers]->(dst:Account)
RETURN TO_JSON(NODES(p)) AS nodes;

結果

ノード
[{"identifier": "...", "properties": {"id": 16}, ...}, {"identifier": "...", "properties": {"id": 20, ...}, ...]
...

PATH_FIRST

PATH_FIRST 関数は、グラフパス内の最初のノードを検索します。セマンティクスの詳細については、PATH_FIRST をご覧ください。

このクエリは、2 つの転送のグラフパス内の最初のノードを検索します。Account ノードのラベルとアカウントのニックネームを返します。

GRAPH FinGraph
MATCH p = -[:Transfers]->{1,3}(dst:Account{id: 7})
RETURN DISTINCT PATH_FIRST(p).id AS can_reach_target;

結果

can_reach_target
7
16
20

PATH_LAST

PATH_LAST 関数は、グラフパスの最後のノードを検索します。セマンティクスの詳細については、PATH_LAST をご覧ください。

このクエリは、2 つの転送のグラフパス内の最後のノードを検索します。Account ノードのラベルとアカウントのニックネームを返します。

GRAPH FinGraph
MATCH p =(start:Account{id: 7})-[:Transfers]->{1,3}
RETURN DISTINCT PATH_LAST(p).id as can_reach_target;

結果

can_reach_target
7
16
20

PATH_LENGTH

PATH_LENGTH 関数は、グラフパス内のエッジの数を検索します。セマンティクスの詳細については、PATH_LENGTH をご覧ください。

このクエリは、1 ~ 3 件の転送を含むグラフパス内のエッジの数を検索します。

GRAPH FinGraph
MATCH p = (src:Account)-[e:Transfers]->{1,3}(dst:Account)
RETURN PATH_LENGTH(p) AS num_transfers, COUNT(*) AS num_paths;

結果

num_transfers num_paths
1 5
2 7
3 11

IS_ACYCLIC

IS_ACYCLIC 関数は、グラフパスに繰り返しノードの有無を確認します。重複が見つかった場合は TRUE を返し、それ以外の場合は FALSE を返します。セマンティクスの詳細については、IS_ACYCLIC をご覧ください。

このクエリは、このグラフパスに重複するノードがあるかどうかを確認します。

GRAPH FinGraph
MATCH p = (src:Account)-[t1:Transfers]->(mid:Account)-[t2:Transfers]->(dst:Account)
RETURN IS_ACYCLIC(p) AS is_acyclic_path, src.id AS source_account_id,
  mid.id AS mid_account_id, dst.id AS dst_account_id;

結果

is_acyclic_path source_account_id mid_account_id dst_account_id
TRUE 16 20 7
TRUE 20 7 16
TRUE 20 7 16
FALSE 16 20 16
TRUE 7 16 20
TRUE 7 16 20
FALSE 20 16 20

IS_TRAIL

IS_TRAIL 関数は、グラフパスに繰り返しエッジがあるかどうかを確認します。重複が見つかった場合は TRUE を返し、それ以外の場合は FALSE を返します。セマンティクスの詳細については、IS_TRAIL をご覧ください。

このクエリは、このグラフパスに重複するエッジがあるかどうかを確認します。

GRAPH FinGraph
MATCH p = (src:Account)-[t1:Transfers]->(mid1:Account)-[t2:Transfers]->
  (mid2:Account)-[t3:Transfers]->(dst:Account)
WHERE src.id < dst.id
RETURN IS_TRAIL(p) AS is_trail_path, t1.id AS t1_id, t2.id AS t2_id, t3.id AS t3_id;

結果

is_trail_path t1_id t2_id t3_id
FALSE 16 20 16
TRUE 7 16 20
TRUE 7 16 20

パスモード

Spanner Graph では、重複するノードとエッジがデフォルトで返されます。次のパスモードを使用すると、指定されたモードに基づいて、ノードとエッジが繰り返されるパスを含めたり除外したりできます。セマンティクスの詳細については、パスモードをご覧ください。

WALK

デフォルトの WALK パスモードでは、ノードやエッジが繰り返されるパスも含め、すべてのパスが保持されます。

次のクエリは、定量化されていないパスパターンで WALK パスモードを使用する方法を示しています。結果の最初のパスでは、t1t3 に同じエッジが使用されています。

GRAPH FinGraph
MATCH p = WALK (src:Account)-[t1:Transfers]->(mid1:Account)-[t2:Transfers]->
  (mid2:Account)-[t3:Transfers]->(dst:Account)
WHERE src.id < dst.id
RETURN t1.id AS transfer1_id, t2.id AS transfer2_id, t3.id AS transfer3_id;

結果

transfer1_id transfer2_id transfer3_id
16 20 16
7 16 20
7 16 20

TRAIL

デフォルトの TRAIL パスモードでは、エッジが繰り返されるパスが除外されます。

次のクエリは、定量化されていないパスパターンで TRAIL パスモードを使用する方法を示しています。t1 エッジと t3 エッジが同じパスは除外されます。

GRAPH FinGraph
MATCH p = TRAIL (src:Account)-[t1:Transfers]->(mid1:Account)-[t2:Transfers]->
  (mid2:Account)-[t3:Transfers]->(dst:Account)
RETURN
  t1.id AS transfer1_id, t2.id AS transfer2_id, t3.id AS transfer3_id;

結果

transfer1_id transfer2_id transfer3_id
16 20 7
16 20 7
20 7 16
20 7 16
7 16 20
7 16 20
7 16 20
7 16 20
20 16 20

パス検索の接頭辞

パス検索接頭辞を使用すると、パスパターンを制限して、各データ パーティションからの最短パスを返すことができます。セマンティクスの詳細については、パス検索接頭辞をご覧ください。

ANY SHORTEST

ANY SHORTEST パス検索接頭辞は、各データパーティションのパターンに一致する最短パス(エッジ数が最も少ないパス)を返します。パーティションごとに最短経路が複数ある場合は、いずれかを返します。

次のクエリは、各 [a, b] ペア間の任意のパスに一致します。

GRAPH FinGraph
MATCH p = ANY SHORTEST (a:Account)-[t:Transfers]->{1,4}(b:Account)
WHERE a.is_blocked
LET total_amount = SUM(t.amount)
RETURN a.id AS account1_id, total_amount, b.id AS account2_id;

結果

account1_id total_amount account2_id
16 500 16
16 800 7
16 300 20

変換規則

詳細については、GRAPH_PATH 変換ルールをご覧ください。

次のステップ