Microsoft Fabricで一般的な GQL クエリを記述する

この記事では、近隣ノードの検索、マルチホップ接続の走査、共有接続の識別、リレーションシップのカウント、接続のないエンティティの検索など、Microsoft Fabricの一般的なグラフ タスクに対する実用的な GQL クエリ パターンについて説明します。

この例では、 ソーシャル ネットワークのサンプル データセットを使用します。 クエリフローと文のエンドツーエンドの説明については、 GQL言語ガイドをご覧ください。 達成したいグラフのタスクが決まったら、この記事を活用してください。 ノード、エッジ、パスパターンの構築に関する体系的な指示については、「 グラフパターンクエリの書き込み」を参照してください。 詳細なフィルタリングおよび集約ワークフローについては、「 グラフデータのフィルタリングおよび集計」をご覧ください。

前提条件

直接の近隣ノードを検索する

開始ノードに接続されているすべてのノードを 1 ホップずつ返します。

特定のユーザーが知っているすべてのユーザーを検索します。

MATCH (p:Person WHERE p.firstName = 'Alice')-[:knows]->(friend:Person)
RETURN friend.firstName, friend.lastName

ユーザーが働いていたすべての会社を検索します。

MATCH (p:Person WHERE p.firstName = 'Alice')-[:workAt]->(c:Company)
RETURN c.name, c.url

友達を探す (マルチホップ)

複数のホップを走査するには、 {min,max} で可変長パターンを使用します。

アリスからちょうど2本のknows辺をたどって到達できる人を見つけてください:

MATCH (alice:Person WHERE alice.firstName = 'Alice')-[:knows]->{2,2}(fof:Person)
RETURN DISTINCT fof.firstName, fof.lastName
LIMIT 100

3 度以内に到達可能な全員を検索します。

MATCH (src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,3}(dst:Person)
RETURN DISTINCT dst.firstName, dst.lastName
LIMIT 100

アリスから4ホップ以内に到達可能な各人への最短経路を1つ見つけてください:

MATCH p = ANY SHORTEST
  (src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,4}(dst:Person)
RETURN dst.firstName, dst.lastName, path_length(p) AS hopCount
ORDER BY hopCount, dst.lastName
LIMIT 100

同じホップ数で複数の最短経路が同じ人物に到達した場合、 ANY SHORTEST 決定論的なタイ選択なしにそのうちの1つを返します。

インライン述語は、どのパスが ANY SHORTEST対象となるかを制約します。 最短経路が選択された後にポストフィルターが適用されます。 例としては、 パス選択の前後に述語を置くことを参照してください。

ヒント

予測可能なクエリコストには有限の上限を用いましょう。 無制限の ALL WALK 移動はサポートされていません。 他の無制限経路モードでも大きな結果を生み出すことができます。 現在の制限事項を参照してください。

エンティティごとのリレーションシップのカウント

GROUP BYでcount(*)を使用して、各エンティティに含まれるリレーションシップの数をカウントします。 詳細なグルーピング、集計フィルタリング、条件付きルーティングパターンについては、「 フィルタおよび集計グラフデータ」を参照してください。

各ユーザーが持っているフレンドの数をカウントし、最も少ないユーザーから順に並べ替えました。

MATCH (p:Person)-[:knows]->(friend:Person)
LET personId = p.id, name = p.firstName || ' ' || p.lastName
RETURN personId, name, count(*) AS friendCount
GROUP BY personId, name
ORDER BY friendCount DESC
LIMIT 20

各事業体の価値を計算してください

相関した CALL サブクエリを使って、各入力行の値を計算します。 外部クエリの変数はサブクエリ内で暗黙的に利用可能です。

各人の友達の数を計算してください:

MATCH (p:Person)
CALL {
  MATCH (p)-[:knows]->(friend:Person)
  RETURN count(*) AS friendCount
}
RETURN p.firstName, p.lastName, friendCount
ORDER BY friendCount DESC

外側の変数は CALL後も利用可能です。 サブクエリ内で作成された変数のうち、外部で利用可能になるのは返された列のみです。 グループ化されていない count(*) は、マッチする友達が存在しない 0 返すため、このクエリは友達がいない人を保持します。

通常の CALL は、サブクエリが行を返さない場合に外側の行を1行削除し、複数の行を返すときは各サブクエリ行に対して1行ずつ出力を生成します。 一致するサブクエリ行がない外側行を保持したい場合には OPTIONAL CALL を使います。

共有接続の検索

パターンの 2 つの部分で変数を再利用すると、暗黙的な "同じノード" 制約が作成されます。 この制約を使用して、共有された 3 番目のエンティティを介して接続されているエンティティを検索します。

両方とも同じ人を知っている人のペアを見つけます。

MATCH (a:Person)-[:knows]->(mutual:Person)<-[:knows]-(b:Person)
WHERE a.id < b.id
RETURN a.firstName, b.firstName, mutual.firstName AS sharedContact
LIMIT 100

同じ会社で働く人のペアを見つけます。

MATCH (c:Company)<-[:workAt]-(a:Person), (c)<-[:workAt]-(b:Person)
WHERE a.id < b.id
RETURN a.firstName, b.firstName, c.name AS company
LIMIT 100

ヒント

WHERE a.id < b.id条件により、重複するペア (Alice-Bob と Bob-Alice) が結果に表示されなくなります。

リレーションシップのないエンティティを検索する

NOT EXISTSを使って、相関したサブクエリが行を返さないノードを見つけてください。

どの会社でも働いていない人を見つけます。

MATCH (p:Person)
WHERE NOT EXISTS {
  MATCH (p)-[:workAt]->(c:Company)
  RETURN c
}
RETURN p.firstName, p.lastName
LIMIT 100

コメントのない投稿を検索する:

MATCH (post:Post)
WHERE NOT EXISTS {
  MATCH (comment:Comment)-[:replyOf]->(post)
  RETURN comment
}
RETURN post.id, post.content
LIMIT 100

多数の接続を持つエンティティを検索する

GROUP BYとFILTERを組み合わせて、高度に接続されたノードを識別します。 この方法は、ハブまたは外れ値を見つけるのに役立ちます。

10 人以上の友人を持つユーザーを見つける:

MATCH (p:Person)-[:knows]->(friend:Person)
LET personId = p.id, name = p.firstName || ' ' || p.lastName
RETURN personId, name, count(*) AS friendCount
GROUP BY personId, name
FILTER friendCount > 10
ORDER BY friendCount DESC

Note

FILTER GROUP BY後は、SQL でのHAVINGと同様に機能します。 個々の行ではなく、集計された結果をフィルター処理します。