グラフクエリの概要

このドキュメントでは、グラフ クエリ言語(GQL)の概要と、BigQuery Graph のグラフ クエリの作成方法について説明します。グラフクエリを実行して、パターンを見つけたり、関係を走査したり、プロパティ グラフから分析情報を取得できます。このドキュメントの例では、人物、所有するアカウント、アカウント間の転送の関係を示す FinGraph というグラフを参照しています。グラフの定義については、FinGraph の例をご覧ください。

クエリの構造

グラフクエリは、グラフの名前と 1 つ以上のリニアクエリ ステートメントで構成されます。各線形クエリには 1 つ以上のステートメントが含まれています。これにより、グラフデータを操作してパターン マッチングを見つけ、変数を定義し、中間データをフィルタして変換し、結果を返すことができます。グラフクエリは、BigQuery で SQL クエリを実行するのと同じ方法で実行します。

グラフクエリ構造の例。
グラフクエリの構造の例。

グラフパターン マッチング

グラフパターン マッチングによって、グラフ内の特定のパターンが検出されます。最も基本的なパターンは要素パターンです。たとえば、ノードと一致するノードパターンや、エッジと一致するエッジパターンなどがあります。

ノードパターン

ノードパターンは、グラフ内のノードと一致します。このパターンには、一致するかっこが含まれています。必要に応じて、グラフパターン変数、ラベル式、プロパティ フィルタを含めることができます。

すべてのノードを検索する

次のクエリは、グラフ内のすべてのノードを返します。グラフパターン変数と呼ばれる変数 n は、一致するノードにバインドされます。この場合、ノードパターンはグラフ内のすべてのノードと一致します。

GRAPH graph_db.FinGraph
MATCH (n)
RETURN LABELS(n) AS label, n.id;

このクエリは labelid を返します。

label id
Account 7
Account 16
Account 20
Person 1
Person 2
Person 3

特定のラベルを持つすべてのノードを検索する

次のクエリは、Person ラベルを持つグラフ内のすべてのノードと一致します。このクエリは、一致したノードのラベルと一部のプロパティを返します。

GRAPH graph_db.FinGraph
MATCH (p:Person)
RETURN LABELS(p) AS label, p.id, p.name;

このクエリは、一致したノードの次のプロパティを返します。

label id name
Person 1 Alex
Person 2 Dana
Person 3 Lee

ラベル式に一致するすべてのノードを検索する

1 つ以上の論理演算子を使用してラベル式を作成できます。たとえば、次のクエリは、Person ラベルまたは Account ラベルを持つグラフ内のすべてのノードと一致します。グラフパターン変数 n は、Person または Account ラベルを持つノードのすべてのプロパティを公開します。

GRAPH graph_db.FinGraph
MATCH (n:Person|Account)
RETURN LABELS(n) AS label, n.id, n.birthday, n.create_time;

このクエリの結果では、次の点に注意してください。

  • すべてのノードに id プロパティがあります。
  • Account ラベルに一致するノードには create_time プロパティがありますが、birthday プロパティはありません。これらのノードの birthday プロパティは NULL です。
  • Person ラベルに一致するノードには birthday プロパティがありますが、create_time プロパティはありません。これらのノードの create_time プロパティは NULL です。
label id birthday create_time
Account 7 NULL 2020-01-10T14:22:20.222Z
Account 16 NULL 2020-01-28T01:55:09.206Z
Account 20 NULL 2020-02-18T13:44:20.655Z
Person 1 1991-12-21T08:00:00Z NULL
Person 2 1980-10-31T08:00:00Z NULL
Person 3 1986-12-07T08:00:00Z NULL

ラベル式とプロパティ フィルタに一致するすべてのノードを検索する

次のクエリは、Person ラベルが付いていて、プロパティ id1 に等しいグラフ内のすべてのノードと一致します。

GRAPH graph_db.FinGraph
MATCH (p:Person {id: 1})
RETURN LABELS(p) AS label, p.id, p.name, p.birthday;

次のような結果になります。

label id name birthday
Person 1 Alex 1991-12-21T08:00:00Z

WHERE 句を使用すると、ラベルとプロパティに対してより複雑なフィルタ条件を作成できます。

次のクエリでは、WHERE 句を使用して、プロパティ birthday1990-01-10 より前のノードをフィルタします。

GRAPH graph_db.FinGraph
MATCH (p:Person WHERE p.birthday < '1990-01-10')
RETURN LABELS(p) AS label, p.name, p.birthday;

次のような結果になります。

label name birthday
Person Dana 1980-10-31T08:00:00Z
Person Lee 1986-12-07T08:00:00Z

エッジパターン

エッジパターンは、ノード間のエッジまたは関係に一致します。エッジパターンは角かっこ([])で囲まれ、記号 --><- などを含み、方向を示します。エッジパターンには、一致するエッジにバインドするグラフパターン変数を必要に応じて含めることができます。

一致するラベルを持つすべてのエッジを検索する

このクエリは、Transfers ラベルを持つグラフ内のすべてのエッジを返します。クエリは、グラフパターン変数 e を一致するエッジにバインドします。

GRAPH graph_db.FinGraph
MATCH -[e:Transfers]->
RETURN e.Id as src_account, e.order_number;

次のような結果になります。

src_account order_number
7 304330008004315
7 304120005529714
16 103650009791820
20 304120005529714
20 302290001255747

ラベル式とプロパティ フィルタに一致するすべてのエッジを検索する

次のクエリのエッジパターンは、ラベル式とプロパティ フィルタを使用して、指定された注文番号に一致する Transfers のラベルが付いたすべてのエッジを検索します。

GRAPH graph_db.FinGraph
MATCH -[e:Transfers {order_number: "304120005529714"}]->
RETURN e.Id AS src_account, e.order_number;

次のような結果になります。

src_account order_number
7 304120005529714
20 304120005529714

任意の方向のエッジパターンを使用してすべてのエッジを検索する

クエリで any direction エッジパターン(-[]-)を使用すると、エッジをどちらの方向であっても照合できます。次のクエリは、ブロックされた口座を含むすべての送金を検索します。

GRAPH graph_db.FinGraph
MATCH (account:Account)-[transfer:Transfers]-(:Account {is_blocked:true})
RETURN transfer.order_number, transfer.amount;

次のような結果になります。

order_number amount
304330008004315 300
304120005529714 100
103650009791820 300
302290001255747 200

パスパターン

パスパターンは、ノードパターンとエッジパターンを交互に組み合わせて作成されます。

パスパターンを使用して、特定のノードからのすべてのパスを検索する

次のクエリは、id2 に等しい Person が所有する口座から開始された、ある口座へのすべての送金を見つけます。

一致した各結果は、id2 に等しい場合の Person ノードから、Owns エッジを使用して接続された Account ノードを経由し、Transfers エッジを使用して別の Account ノードに至るパスを表します。

GRAPH graph_db.FinGraph
MATCH
  (p:Person {id: 2})-[:Owns]->(account:Account)-[t:Transfers]->
  (to_account:Account)
RETURN
  p.id AS sender_id, account.id AS from_id, to_account.id AS to_id;

次のような結果になります。

sender_id from_id to_id
2 20 7
2 20 16

定量化されたパスパターン

定量化されたパターンは、指定された範囲内でパターンを繰り返します。

定量化されたエッジパターンを照合する

可変長のパスを見つけるには、エッジパターンに数量子を適用します。次のクエリは、id の値が 7 の送金元 Account から 1 ~ 3 回送金した送金先口座を検索することで、これを示しています。

このクエリは、数量子 {1, 3} をエッジパターン -[e:Transfers]-> に適用します。これにより、Transfers エッジパターンを 1 回、2 回、または 3 回繰り返すパスに一致するようにクエリが指示されます。WHERE 句は、結果から移行元アカウントを除外するために使用されます。ARRAY_LENGTH 関数は、group variable e にアクセスするために使用されます。

GRAPH graph_db.FinGraph
MATCH (src:Account {id: 7})-[e:Transfers]->{1, 3}(dst:Account)
WHERE src != dst
RETURN src.id AS src_account_id, ARRAY_LENGTH(e) AS path_length, dst.id AS dst_account_id;

次のような結果になります。

src_account_id path_length dst_account_id
7 1 16
7 1 16
7 3 16
7 3 16
7 2 20
7 2 20

結果の一部が重複しています。これは、同じソースノードと宛先ノードの間にパターンに一致する複数のパスが存在する可能性があり、クエリがそれらをすべて返すためです。

定量化されたパスパターンを照合する

次のクエリは、ブロックされている中間口座を経由する 1~2 つの Transfers エッジを持つ Account ノード間のパスを見つけます。

かっこで囲まれたパスパターンは定量化され、その WHERE 句で繰り返しパターンの条件を指定します。

GRAPH graph_db.FinGraph
MATCH
  (src:Account)
  ((a:Account)-[:Transfers]->(b:Account {is_blocked:true}) WHERE a != b){1,2}
    -[:Transfers]->(dst:Account)
RETURN src.id AS src_account_id, dst.id AS dst_account_id;

次のような結果になります。

src_account_id dst_account_id