グラフクエリの概要
このドキュメントでは、グラフ クエリ言語(GQL)の概要と、BigQuery Graph のグラフ クエリの作成方法について説明します。グラフクエリを実行して、パターンを見つけたり、関係を走査したり、プロパティ グラフから分析情報を取得できます。このドキュメントの例では、人物、所有するアカウント、アカウント間の転送の関係を示す FinGraph というグラフを参照しています。グラフの定義については、FinGraph の例をご覧ください。
クエリの構造
グラフクエリは、グラフの名前と 1 つ以上のリニアクエリ ステートメントで構成されます。各線形クエリには 1 つ以上のステートメントが含まれています。これにより、グラフデータを操作してパターン マッチングを見つけ、変数を定義し、中間データをフィルタして変換し、結果を返すことができます。グラフクエリは、BigQuery で SQL クエリを実行するのと同じ方法で実行します。
グラフパターン マッチング
グラフパターン マッチングによって、グラフ内の特定のパターンが検出されます。最も基本的なパターンは要素パターンです。たとえば、ノードと一致するノードパターンや、エッジと一致するエッジパターンなどがあります。
ノードパターン
ノードパターンは、グラフ内のノードと一致します。このパターンには、一致するかっこが含まれています。必要に応じて、グラフパターン変数、ラベル式、プロパティ フィルタを含めることができます。
すべてのノードを検索する
次のクエリは、グラフ内のすべてのノードを返します。グラフパターン変数と呼ばれる変数 n は、一致するノードにバインドされます。この場合、ノードパターンはグラフ内のすべてのノードと一致します。
GRAPH graph_db.FinGraph
MATCH (n)
RETURN LABELS(n) AS label, n.id;
このクエリは label と id を返します。
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 ラベルが付いていて、プロパティ id が 1 に等しいグラフ内のすべてのノードと一致します。
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 句を使用して、プロパティ birthday が 1990-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 |
パスパターン
パスパターンは、ノードパターンとエッジパターンを交互に組み合わせて作成されます。
パスパターンを使用して、特定のノードからのすべてのパスを検索する
次のクエリは、id が 2 に等しい Person が所有する口座から開始された、ある口座へのすべての送金を見つけます。
一致した各結果は、id が 2 に等しい場合の 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 |
|---|---|