グラフ パターン マッチングを使用すると、直感的で視覚的な構文を使用して、検索するデータの構造を記述できます。 テーブルを結合する代わりに、リレーションシップ自体 (エッジで接続されたノード) のようなパターンを記述します。 この記事では、Microsoft Fabricのグラフで一般的なシナリオの GQL パターン クエリを記述する方法について説明します。
この例では、 ソーシャル ネットワークのサンプル データセットを使用します。 完全なパターン構文リファレンスについては、 GQL グラフ パターンを参照してください。
前提条件
- データが読み込まれたグラフ項目。 グラフを初めて使用する場合は、最初に チュートリアル を完了します。
- 基本的な
MATCHとRETURNクエリに関する知識。 GQL 言語ガイドを参照してください。
直接的な関係を照合する
基本パターンは、ノードタイプ、特定のエッジタイプ、および別のノードタイプと一致します。 構文はリレーションシップの図のようになります。
たとえば、会社と組み合わせて最大 100 人を検索するには、次の操作を行います。
MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName, p.lastName, c.name
LIMIT 100
方向がわからない場合、または方向を気にしない場合は、無向エッジ パターンを使用します。 たとえば、接続を開始したユーザーに関係なく、最大 100 人の相互知人を見つけるには、次のようにします。
MATCH (a:Person)-[:knows]-(b:Person)
RETURN a.firstName, b.firstName
LIMIT 100
Note
グラフでは現在、無向エッジの作成はサポートされていませんが、 -[:label]- 構文を使用して任意の方向にエッジを照会できます。
インライン WHERE を使用してパターンをフィルター処理する
パターン内に WHERE を配置して、ノードとエッジが一致するようにフィルター処理します。 この方法は、事後のフィルター処理よりも効率的です。
たとえば、1990 年より前に生まれ、名前が "A" で始まる会社で働いている人を見つけるには、次のようにします。
MATCH (p:Person WHERE p.birthday < 19900101)-[:workAt]->(c:Company WHERE c.name STARTS WITH 'A')
RETURN p.firstName, p.lastName, c.name
エッジ プロパティでフィルター処理して、一致するリレーションシップを制限します。 たとえば、2010 年以降に会社で働き始めた人のみを返すには、次のようにします。
MATCH (p:Person)-[w:workAt WHERE w.workFrom >= 2010]->(c:Company)
RETURN p.firstName, c.name, w.workFrom
マルチホップの関係にマッチする
可変長パターンを使用して、1 つの式で複数のホップを走査します。
{min,max}構文でホップの最小数と最大数を指定します。
たとえば、Aliceを中心にして、友人関係の距離が2から4の範囲にある最大100人のユーザーを見つけるには、次のようにします。
MATCH (src:Person WHERE src.firstName = 'Alice')-[:knows]->{2,4}(dst:Person)
RETURN dst.firstName, dst.lastName
LIMIT 100
Alice から最大 100 の即時および 2 次接続 (1 つまたは 2 つのホップ) を検索するには:
MATCH (src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,2}(dst:Person)
RETURN DISTINCT dst.firstName, dst.lastName
LIMIT 100
パス モードを使用したトラバーサルの制御
既定では、GQL は TRAIL モードを使用します。これにより、同じエッジが複数回走査されなくなります。 異なる保証が必要な場合は、パス モードを明示的に使用します。
| パス モード | Behavior | 次の場合に使用... |
|---|---|---|
WALK |
ノードとエッジを繰り返し使用できます | 制限のないありのままのトラバーサルが必要です。 ほとんど必要ありません。探索的クエリに主に役立ちます。 |
TRAIL |
エッジを繰り返さない (既定値) | 同じリレーションシップを再トレースしないようにする必要がありますが、同じノードが異なるリレーションシップを介して表示される場合があります。 ほとんどのトラバーサル クエリに適しています。 |
SIMPLE |
開始ノードと終了ノードを除き、ノードが繰り返されないようにする | パスの途中にノードを複数回表示する必要はありませんが、開始に近いパスを許可します。 ループを検出するのに役立ちます。 |
ACYCLIC |
ノードをまったく繰り返さない | パス内の任意の場所に 2 回以上ノードが表示されていないことを保証する必要があります。 厳密な階層、系列、またはノードを再訪すると正しくない結果が生成されるトラバーサルに使用します。 |
WALK は最も制限の厳しいモードであり、 ACYCLIC は最も制限が厳しいモードです。
TRAIL は既定値であり、ほとんどのクエリに適しています。 より制限の厳しいモードは、ユース ケースで必要な場合にのみ使用してください。
違いを説明するために、Alice → Bob → Carol → Bob のパスを考えてみましょう。
- WALK — このパスを許可します。 ノードとエッジは自由に繰り返すことができます。
- TRAIL — このパスを許可します。 Bob は 2 回表示されますが、使用される各エッジは異なるリレーションシップ (Alice→Bob と Carol→Bob は異なるエッジであるため、エッジは繰り返されません。
- SIMPLE — このパスをブロックします。 Bobは複数回現れますが、SIMPLEでは、ノードがパスの始まりと終わりの両方(閉ループ)である場合にのみ、そのノードを繰り返すことができます。 ここでは Alice が始まり、Bob が最後なので、例外は適用されません。
- ACYCLIC — このパスをブロックします。 Bob はパス内の任意の場所に複数回表示されます。
次の例では、 TRAIL を使用して、4 つのホップ内で Alice のネットワークで到達可能な最初の 100 人の各ユーザーにつながる個別のパスの数をカウントする方法を示します。
MATCH TRAIL (src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,4}(dst:Person)
RETURN dst.firstName, dst.lastName, count(*) AS pathCount
LIMIT 100
ACYCLICを使用して、各ユーザーが一意であるパスを通じて、Alice から4つのホップ以内で到達できる最大100人を返します。
MATCH ACYCLIC (src:Person WHERE src.firstName = 'Alice')-[:knows]->{1,4}(dst:Person)
RETURN dst.firstName, dst.lastName
LIMIT 100
ヒント
大きなグラフの場合は、常に可変長パターン ({1,4}ではなく{1,}) に上限を設定します。 高密度グラフ間の無制限トラバーサルは、クエリのタイムアウト制限に達する可能性があります。
現在の制限事項を参照してください。
変数の再利用を使用して共有エンティティを表現する
パターンの 2 つの部分で同じ変数を再利用すると、暗黙的な等値制約が作成されます。両方の参照が同じノードと一致する必要があります。 この手法を使用すると、"共有された 3 番目のエンティティを介して接続されているエンティティを見つける" を表現できます。
たとえば、お互いを知り、同じ会社で働いている人を最大 100 組見つけるには、次のようにします。
MATCH (c:Company)<-[:workAt]-(a:Person)-[:knows]-(b:Person)-[:workAt]->(c)
RETURN a.firstName, b.firstName, c.name
LIMIT 100
変数 c は両方の workAt ターゲットに再利用されるため、クエリは両方のユーザーが互いを認識 し 、同じ会社で働いているペアのみを返します。
同じ投稿が好きな人を最大 100 組見つけるには:
MATCH (a:Person)-[:likes]->(post:Post)<-[:likes]-(b:Person)
WHERE a.id < b.id
RETURN a.firstName, b.firstName, post.id
LIMIT 100
ヒント
WHERE a.id < b.id条件により、重複するペア (Alice + Bob と Bob + Alice) が結果に表示されなくなります。
複数のパターンを結合する
1 つの MATCHで複数のパターンをコンマで区切って一覧表示します。 すべてのパターンが正しく結合されるように、少なくとも 1 つの変数を共有する必要があります。
たとえば、職場と住んでいる都市の両方と共に最大 100 人を見つけるには、次のようにします。
MATCH (p:Person)-[:workAt]->(c:Company),
(p)-[:isLocatedIn]->(city:City)
RETURN p.firstName, c.name AS company, city.name AS city
LIMIT 100
共有変数 p は、2 つのパターンを接続します。 各結果行は、会社と市区町村を持つ 1 人のユーザーを表します。
省略可能なリレーションシップを一致させる
すべてのノードにリレーションシップが存在しない可能性がある場合は、 OPTIONAL MATCH を使用します。 一致しない行は、SQL NULLと同様に、LEFT JOIN値で保持されます。
たとえば、会社名を持つ最大 100 人を返します。これには、雇用主がいないユーザー (つまり、会社の列の NULL を返すユーザー) が含まれます。
MATCH (p:Person)
OPTIONAL MATCH (p)-[:workAt]->(c:Company)
RETURN p.firstName, p.lastName, c.name AS company
LIMIT 100
IS NULL後にOPTIONAL MATCHを使用して、会社で働いていない最大 100 人を検索します。
MATCH (p:Person)
OPTIONAL MATCH (p)-[:workAt]->(c:Company)
FILTER c IS NULL
RETURN p.firstName, p.lastName
LIMIT 100