次の方法で共有


GQL グラフ パターン

現在、この機能はパブリック プレビュー段階にあります。 このプレビュー版はサービス レベル アグリーメントなしで提供されています。運用環境のワークロードに使用することはお勧めできません。 特定の機能はサポート対象ではなく、機能が制限されることがあります。 詳細については、「 Microsoft Azure プレビューの追加使用条件」を参照してください。

グラフ パターンは、GQL クエリの主要な構成要素です。 これらは、直感的で視覚的な方法でノードとエッジを使用して、グラフ内で探している構造を記述します。 グラフ パターンは、クエリ エンジンがグラフ内の実際のデータと照合しようとするテンプレートと考えてください。

Important

この記事では、 ソーシャル ネットワークのグラフ データセットの例のみを使用します。

単純な要素パターン

単純な要素パターンは、特定の要件を満たすグラフの個々のノードとエッジを照合するのに役立ちます。 これらのパターンは、より複雑なパターン マッチングの基礎を形成します。

単純なノード パターン

ノード パターンは、ノードが一致する必要があるラベルとプロパティを指定します。

(:City { name: "New York" })

このパターンは、ラベルとPlaceラベル (City 演算子で示されます) の&を持ち、name プロパティが"New York"等しいすべてのノードと一致します。 必要なラベルとプロパティのこの仕様は、ノード パターンの フィラー と呼ばれます。

主な概念:

  • ラベルの一致: 複数のラベルを要求するには、 & を使用します。
  • プロパティのフィルター処理: プロパティが一致する必要がある正確な値を指定します。
  • 柔軟な ("共変") 一致: 一致するノードは、指定されたラベルとプロパティを超えるラベルとプロパティを持つことができます。

複数要素ラベルを持つグラフモデルはまだサポートされていません(既知の問題)。

シンプルなエッジ パターン

エッジ パターンは、ノード パターンよりも複雑です。 入力口を指定するだけでなく、ソース ノード パターンを宛先ノード パターンに接続することもできます。 エッジ パターンでは、エッジとそのエンドポイントの両方の要件について説明します。

(:Person)-[:likes|knows { creationDate: ZONED_DATETIME("2010-08-31T13:16:54Z") }]->(:Comment)

矢印の方向 -[...]-> は重要です。ソース ノード パターンとして (:Person) を決定し、宛先ノード パターンとして (:Comment) します。 エッジの方向を理解することは、グラフのクエリを正しく行う上で非常に重要です。

同等のミラー化されたパターン:

矢印を反転し、ノード パターンを入れ替えて、同等のミラー化されたエッジ パターンを作成できます。

(:Comment)<-[:likes { creationDate: ZONED_DATETIME("2010-08-31T13:16:54Z") }]-(:Person)

このパターンは、同じリレーションシップを検出しますが、逆の観点から見ると見なされます。

任意向きのエッジ パターン

グラフ エッジの方向がクエリに関係ない場合は、任意の方向のエッジ パターンを作成することで、その方向を指定しないようにすることができます。

(:Song)-[:inspired]-(:Movie)

このパターンは、どのノードがソースで宛先であるかに関係なく、 (:Song)-[:inspired]->(:Movie)(:Movie)-[:inspired]->(:Song) 結合と同じエッジに一致します (この例はソーシャル ネットワーク グラフの種類ではありません)。

グラフ エッジ パターンのショートカット

GQL には、クエリをより簡潔にするために、一般的なエッジ パターンに便利なショートカットが用意されています。

  • ()->() は、 ()-[]->() (任意のラベルを持つ有向エッジ) を表します。
  • ()<-() は、 ()<-[]-() を表します (任意のラベルと逆の方向のエッジ)
  • ()-() は、 ()-[]-() (任意のラベルを持つ任意の向きのエッジ) を表します

これらのショートカットは、接続性を考慮するが、特定のグラフ エッジの種類については考慮しない場合に役立ちます。

ラベル式

パターンは、一致するノードとエッジのラベルに複雑な要件を表すことができます。

Example:

MATCH (:Person|(Organization&!Company))-[:isLocatedIn]->(p:City|Country)
RETURN count(*) AS num_matches

これにより、isLocatedInノードまたはPersonノードにOrganizationノードまたはCompanyUniversityノード (ソーシャル ネットワーク スキーマ内のノードは常にCity) を接続するCountryエッジの数がカウントされます。

構文 :

構文 Meaning
A&B ラベルには、A と B の両方を含める必要があります。
A|B ラベルには、A または B の少なくとも 1 つを含める必要があります。
!A ラベルは A を除外する必要があります。

さらに、かっこを使用して、ラベル式の評価の順序を制御します。 既定では、 ! は最も優先順位が高く、 &|よりも優先順位が高くなります。 したがって、 !A&B|C|!D((!A)&B)|C|(!D)と同じです。

変数のバインド

変数を使用すると、クエリの他の部分で一致するグラフ要素を参照できます。 強力なクエリを作成するには、変数をバインドして使用する方法を理解することが不可欠です。

要素変数のバインド

ノード パターンとエッジ パターンの両方で、後で参照できるように、一致するノードとエッジを変数にバインドできます。

(p:Person)-[w:workAt]->(c:Company)

このパターンでは、pは一致するPerson ノードにバインドされ、一致するwエッジにworkAtされ、一致するc ノードにCompanyされます。

構造上の制約に対する変数の再利用:

パターン内で同じ変数を複数回再利用すると、一致の構造に対する制限が表されます。 同じ変数が出現するたびに、有効な一致で常に同じグラフ要素にバインドする必要があります。 変数の再利用は、複雑な構造要件を表現するために強力です。

(c:Company)<-[:workAt]-(x:Person)-[:knows]-(y:Person)-[:workAt]->(c:Company)

このパターンは、互いを認識し、変数Personにバインドされている同じxで動作するyCompanycノードを検索します。 cを再利用することで、両方のユーザーが同じ会社で作業できるようになります。

要素変数を持つパターン述語:

要素変数をバインドすると、ノードとエッジ パターンの述語を指定できます。 { name: "New York, USA" }のような正確なプロパティ値を入力者に提供する代わりに、入力者は候補要素ごとに評価される述語を指定できます。 このパターンは、述語が TRUEに評価された場合にのみ一致します。

(p:Person)-[e:knows WHERE e.creationDate >= ZONED_DATETIME("2000-01-01T18:00:00Z")]-(o:Person)

エッジ パターンは、2000 年 1 月 1 日以降、完全一致ではなく柔軟な条件を使用して、お互いを知り合っているユーザーを見つけます。

エッジ パターン変数は、可変長パターンを使用する場合でも、エッジ パターン述語の個々のエッジに常にバインドされます。 これは、ポストフィルターを実行するためにエッジ グループ リスト変数をアンネストする必要がない場合に役立ちます。 「可変長パターンエッジ変数のバインド」を参照してください。

高度なパターン述語手法:

パターン述語は、クエリの読みやすさを向上させる強力なインライン フィルター機能を提供します。

-- Multiple conditions in node predicates
MATCH (p:Person WHERE p.age > 30 AND p.department = 'Engineering')
      -[:workAt]->
      (c:Company WHERE c.revenue > 1000000 AND c.location = 'Seattle')

-- Complex edge predicates with calculations
MATCH (p1:Person)-[w:workAt WHERE w.start_date < ZONED_DATETIME('2020-01-01T00:00:00Z') 
                              AND w.salary > 75000]-(c:Company)

-- MATCH WHERE: evaluated after pattern matching
MATCH (p:Person)-[:workAt]->(c:Company)
WHERE p.active = TRUE AND c.public = TRUE

-- Filter during matching and after
MATCH (p:Person WHERE p.department = 'Sales')-[:workAt]->(c:Company)
WHERE p.quota_achievement > 1.2 AND c.revenue > c.revenue_target

ヒント

条件が高度に選択されている場合にパターン述語を使用すると、中間結果のサイズを小さくできます。

バインド パス変数

さらに処理したり、完全なパス構造をユーザーに返したりするために、一致したパスをパス変数にバインドすることもできます。

p=(c:Company)<-[:workAt]-(x:Person)-[:knows]-(y:Person)-[:workAt]->(c:Company)

ここで、 p は、指定された順序ですべてのノードとエッジの参照値を含む、完全に一致するパス構造を表すパス値にバインドされます。

バウンドパスはユーザーに返すか、 NODESEDGESなどの関数でさらに処理されることがあります。

MATCH p=(c:Company)<-[:workAt]-(x:Person)-[:knows]-(y:Person)-[:workAt]->(c:Company)
LET path_edges = edges(p)
RETURN path_edges, size(path_edges) AS num_edges
GROUP BY path_edges

パターンの作成

実際のクエリでは、多くの場合、単純なノード エッジ ノード構造よりも複雑なパターンが必要です。 GQL には、高度なグラフ トラバーサルのパターンを作成するいくつかの方法が用意されています。

パス パターンを作成する

パス パターンは、単純なノードパターンとエッジ パターンを連結して、より長いトラバーサルを作成することによって構成できます。

(:Person)-[:knows]->(:Person)-[:workAt]->(:Company)-[:isLocatedIn]->(:Country)-[:isPartOf]->(:Continent)

このパターンは、仕事仲間の会社がどこにあるかを見つけるために、ソーシャルおよびプロフェッショナルなつながりを通じて人から走査します。

段階的なパターンの構築: パス パターンを段階的に構築することもできます。これによって、複雑なパターンを読みやすく理解しやすくなります。

(:Person)-[:knows]->(p:Person),
(p:Person)-[:workAt]->(c:Company),
(c:Company)-[:isLocatedIn]->(:Country)-[:isPartOf]->(:Continent)

この方法では、同じトラバーサルが論理的な手順に分割され、理解とデバッグが容易になります。

非線形パターンを作成する

パターンの結果の形状は、線形パスである必要はありません。 中心ノードから放射される "星形" パターンのようなより複雑な構造を照合できます。

(p:Person),
(p)-[:studyAt]->(u:University),
(p)-[:workAt]->(c:Company),
(p)-[:likes]-(m)

このパターンでは、教育、雇用、コンテンツの好みと共に、包括的なプロファイル クエリである人物を一度に検索します。

一致する証跡

複雑なパターンでは、多くの場合、同じエッジを複数回走査することは望ましくありません。 エッジの再利用は、実際のグラフに無限または過度に長いパスにつながる可能性のあるサイクルが含まれている場合に重要になります。 エッジの再利用を処理するために、Microsoft Fabric のグラフでは、 TRAIL 一致モードがサポートされています。

パス パターンの前にキーワード TRAIL を付け、同じエッジを複数回バインドするすべての一致が破棄されます。

TRAIL (a)-[e1:knows]->(b)-[e2:knows]->(c)-[e3:knows]->(d)

TRAILを使用すると、パターンはすべてのエッジが異なる一致のみを生成します。 したがって、パスが特定の一致でサイクルを形成するようにc = a場合でも、e3e1と同じエッジにバインドされることはありません。

TRAIL モードは、無限ループを防ぎ、クエリが意味のある、非冗長なパスを確実に返すようにするために不可欠です。

可変長パターンを使用する

可変長パターンは、反復的なパターン仕様を記述することなく、さまざまな長さのパスを見つけることができる強力なコンストラクトです。 階層、ソーシャル ネットワーク、最適なパスの長さが事前にわかっていないその他の構造を走査するために不可欠です。

境界付き可変長パターン

Important

現在、境界付き可変長パターンでは最大上限 8 のみがサポートされています。 現在の 制限事項に関する記事を参照してください。

多くの一般的なグラフ クエリでは、同じエッジ パターンを複数回繰り返す必要があります。 次のような詳細なパターンを記述する代わりに、

(:Person)-[:knows]->(:Person)-[:knows]->(:Person)-[:knows]->(:Person)

より簡潔な可変長構文を使用できます。

(:Person)-[:knows]->{3}(:Person)

{3}は、-[:knows]->エッジ パターンを 3 回正確に繰り返す必要があることを指定します。

柔軟な繰り返し範囲: 柔軟性を高めるために、繰り返しの下限と上限の両方を指定できます。

(:Person)-[:knows]->{1, 3}(:Person)

このパターンは、直接のフレンド、フレンドのフレンド、フレンドのフレンドをすべて 1 つのクエリで検索します。

下限は 0することもできます。 この場合、エッジは一致せず、2 つのエンドポイント ノード パターンが同じノードと一致する場合にのみ、パターン全体が一致します。

例:

(p1:Person)-[r:knows WHERE NOT p1=p2]->{0,1}(p2:Person)

このパターンは、お互いを知っている異なる人のペアをマッチさせる だけでなく、 同じ人物が p1p2 の両方にマッチするのです。たとえその人が自分自身を「知らなくても」です。

下限が指定されていない場合、通常は 0 (ゼロ) に設定されます。

複素可変長合成: 可変長パターンは、以下のクエリのように、より大きく複雑なパターンの一部となることがあります。

MATCH (c1:Comment)<-[:likes]-(p1:Person)-[:knows]-(p2:Person)-[:likes]->(c2:Comment),
      (c1:Comment)<-[:replyOf]-{1,3}(m)-[:replyOf]->{1,3}(c2:Comment)
RETURN *
LIMIT 100

パターンは、お互いを知っている人が異なるコメントを好むコメントのペアを見つけ、それらのコメントはそれぞれ1〜5レベルの応答チェーンを介して接続されています。

可変長パターンのエッジ変数をバインドする

可変長エッジ パターンをバインドすると、参照コンテキストに応じてエッジ変数の値と型が変わります。 この動作を理解することは、可変長の一致を正しく処理するために重要です。

2 つの参照度:

  • 可変長パターン内: グラフ エッジ変数は、一致したパス ("シングルトン参照度" とも呼ばれます) に沿って個々のエッジにバインドされます。
  • 可変長パターンの外側: グラフ エッジ変数は、一致したパス ("グループ参照の次数" とも呼ばれます) に沿ってすべてのエッジのシーケンスにバインドされます。

両方のコンテキストを示す例:

MATCH (:Person)-[e:knows WHERE e.creationDate >= ZONED_DATETIME("2000-01-01T00:00:00Z")]->{1,3}()
RETURN e[0]
LIMIT 100

エッジ変数 e の評価は、次の 2 つのコンテキストで行われます。

  • MATCHステートメント: クエリは、2000 年以降に各フレンドシップが確立されたフレンドのフレンドのチェーンを検索します。 パターン マッチング中、エッジ パターン述語 e.creationDate >= ZONED_DATETIME("2000-01-01T00:00:00Z") は、候補エッジごとに 1 回評価されます。 このコンテキストでは、 e は単一のエッジ参照値にバインドされます。

  • RETURNステートメント: ここでは、eは、一致したチェーン内で発生する順序でエッジ参照値の (グループ) リストにバインドされます。 e[0]の結果は、一致した各チェーンの最初のエッジ参照値です。

水平集約における可変長パターンのエッジ変数:

可変長パターンマッチングで境界付けられた辺変数は可変長パターンの外にあるグループリストであり、水平集約に利用可能です。

MATCH (a:Person)-[e:knows WHERE e.creationDate >= ZONED_DATETIME("2000-01-01T00:00:00Z")]->{1,3}(b)
RETURN a, b, size(e) AS num_edges
LIMIT 100

詳細は 水平集約 のセクションを参照してください。