Microsoft Fabric のグラフの GQL 言語ガイド

GQL (Graph クエリ言語) は、グラフ データベースの ISO で標準化されたクエリ言語です。 GQL を使用して、Microsoft Fabric のグラフを使用してグラフ データのクエリ、分析、操作を効率的に行います。

SQL を標準化する同じ ISO 作業グループが GQL を開発します。 その結果、GQL は、式、述語、データ型など、多くの概念を SQL と共有します。 SQL の経験がある場合は、その知識の多くを GQL に適用できます。

この記事はグラフにおけるGQLのエンドツーエンドガイドです。 言語がどのように組み合わさるかを説明し、完全な構文や型の詳細のために焦点を絞った参考文献へのリンクをつけています。 以下が対象です。

  • コア概念: グラフ データ構造、パターン、クエリの基礎
  • 重要な文: MATCH、 FILTER、 LET、 WHEN、 ORDER BY、 LIMIT、そして RETURN
  • データ型と式: 値型、演算子、および組み込み関数
  • 高度な手法: 複数ステートメント構成、変数スコープ、集計戦略

言語のウォークスルーではなくタスク志向のガイダンスをお探しなら、ハウツーガイドをご覧ください:

詳細な情報が必要な場合は、焦点を絞った参考文献を活用してください:

必要な情報 決定版記事
構文の概要 GQL クイック リファレンス
ノード、エッジ、パス、パターンの合成構文 GQL グラフ パターン
演算子、述語、関数 GQL 式、述語、および関数
文字通りの構文、値の挙動、型変換 GQL 値と値型
グラフ型の定義と制約 GQL グラフの種類
現在のISO GQL機能カバレッジ GQL標準適合性
現在のFabric特有の制限と制限 現在の制限

[前提条件]

開始する前に、次の概念を理解していることを確認してください。

  • データベースの基本理解 - リレーショナル (SQL)、NoSQL、グラフなどのデータベース システムを使用した経験が役立ちます。
  • グラフの概念 - 接続されたデータ内のノード、エッジ、リレーションシップの理解。
  • クエリの基礎 - フィルター処理、並べ替え、集計などの基本的なクエリの概念に関する知識。

推奨される背景:

  • SQL または openCypher 言語の経験により、GQL 構文の学習が容易になります (これらは GQL のルートです)。
  • データ モデリングに関する知識は、グラフ スキーマの設計に役立ちます。
  • グラフ データの特定のユース ケースについて理解します。

必要なもの:

  • クエリ機能を持つグラフ ワークスペースへのアクセス。
  • ソーシャル ネットワークの例を使用するサンプル データまたは意欲。
  • クエリを記述するための基本的なテキスト エディター。

ヒント

グラフ データベースを初めて使用する場合は、このガイドに進む前に 、グラフ データ モデルの概要 から始めてください。

GQL を特別なものにするもの

GQLはグラフデータ専用に設計されているため、その構文はエンティティ間のつながりを直接表現しています。 SQLが一般的にテーブル間の結合を通じて関係を表現するのに対し、GQLはデータの図に似たグラフパターンを使用します。

例えば、以下のクエリは、互いに知り合いで、どちらも1999年以前に生まれた人々のペアを見つけます。

MATCH (person:Person)-[:knows]-(friend:Person)
WHERE person.birthday < 19990101
  AND friend.birthday < 19990101
RETURN person.firstName || ' ' || person.lastName AS person_name,
       friend.firstName || ' ' || friend.lastName AS friend_name

パターン (person:Person)-[:knows]-(friend:Person) はそれに合わせた関係構造を示しています。 変数は2人をバインドし、クエリがフィルターしてプロパティを返すのです。

GQL の基礎

これらの概念がGQLの基盤を形成しています。

  • グラフは ラベルとプロパティを持つノードと辺を含みます。
  • グラフタイプは 、グラフ内で許可されるノードタイプ、エッジタイプ、制約を正式に定義します。
  • クエリは 、 MATCH、 FILTER、 RETURN などの文を使ってデータを処理し、結果を生成します。
  • パターンは それに対応するグラフ構造を表します。
  • 式は 値を計算し、変換し、比較します。
  • 述語 は条件を検証するために使われるブール式です。
  • 値型は クエリが処理できる値の種類やグラフプロパティが保存できる値を定義します。

グラフデータの理解

GQLを使うには、言語が問い合わせるラベル付きプロパティグラフ構造を理解する必要があります。

ノードとエッジ: 構成要素

ラベル付きプロパティグラフには、2種類のグラフ要素が含まれます。

  • ノードは通常 、人、組織、ポスト、製品などのエンティティを表します。
  • エッジは ノード間のつながりを表し、例えば人が他の人を知っている、あるいは会社で働いているといった形です。

すべてのグラフ要素は内部の同一性、1つ以上のラベル、そして一連の性質を持っています。 ラベルは Person や knowsなどの要素を分類します。 プロパティは firstName: 'Alice' や birthday: 19730108uのような名前と値のペアです。 グラフでは、辺は常に正確に1つのラベルを持ちます。

各辺は、原点とターゲットの2つのノードを正確に接続します。 エッジの方向はグラフ構造の一部です。 例えば、 workAt エッジは Person 原点を Company ターゲットに接続することができます。

注

現在、グラフは無向辺の作成をサポートしていません。 既存の有向辺は、 -[:knows]-のような任意の有向辺パターンを使うことで、どちらの方向にもクエリできます。

グラフは良形で、すべての辺は同じグラフ内に存在する2つのノードをつなげます。

グラフ モデルとグラフの種類

Fabricグラフモデルは、グラフ内で利用可能なノードタイプ、エッジタイプ、プロパティ、ソースマッピング、キーを定義します。 どのソーステーブル行がノードやエッジとなり、それらの要素がどのように接続されるかを指定します。 モデリングの指針については「 グラフスキーマの設計」を参照してください。

GQL標準は、許可されたノードタイプ、エッジタイプ、プロパティ、制約を形式的に記述するために グラフタイプ を使用します。 グラフタイプはFabricグラフモデルで表現される構造の言語レベルの対応物ですが、Graphは現在GQLグラフ型宣言を直接受け付けていません。 形式的な構文や概念については、 GQLグラフの種類を参照してください。

このガイドで使用されている例グラフ

例としては、人、場所、組織、メッセージ、タグ、そしてそれらをつなぐエッジを含む ソーシャルネットワークサンプルデータセットが使われます。

サンプルグラフは以下の領域をつなげています:

  • 人は他の人を知っていて、企業で働き、大学で勉強しています。
  • 都市、国、地域、大陸は地理的な階層を形成します。
  • フォーラムには投稿があり、人々は投稿やコメントを投稿します。
  • タグはコンテンツを分類し、人々の興味を表します。

ソーシャル ネットワーク スキーマを示す図。

完全な例構造については、 ソーシャルネットワークスキーマの例を参照してください。 一般的なグラフの概念については、 ラベル付きプロパティグラフを参照してください。

最初の GQL クエリ

グラフの基本を理解したので、GQL を使用してグラフ データのクエリを実行する方法を見てみましょう。 これらの例は単純なものから複雑なものまで構築されており、GQL のアプローチによってグラフ クエリが直感的かつ強力になるしくみがわかります。

シンプルなスタート:すべての人を見つける

可能な限り最も基本的なクエリから始めます。 グラフ内のすべてのユーザー (:Person) の名前 (名、姓) を見つけます。

MATCH (p:Person)
RETURN p.firstName, p.lastName

このクエリは次のように実行されます。

  1. MATCH は、 Personラベルが付いたすべてのノードを検索します。
  2. RETURN 名と姓が表示されます。

フィルター処理の追加: 特定のユーザーを検索する

次に、特定の特性を持つユーザーを見つけます。 この場合は、Alice という名前の全員を見つけて、名前と誕生日を表示します。

MATCH (p:Person)
FILTER p.firstName = 'Alice'
RETURN p.firstName, p.lastName, p.birthday

このクエリは次のように実行されます。

  1. MATCH は、Person というラベルが付いたすべてのノード (p) を検索します。
  2. FILTER 名が Alice であるノード (p)。
  3. RETURN には、名、姓、誕生日が表示されます。

基本的なクエリ構造

基本的な GQL クエリはすべて一貫したパターンに従います。これは、データを検索、フィルター処理、および返すために連携する一連のステートメントです。 ほとんどのクエリは、グラフ内のパターンを見つけるための MATCH で始まり、出力を指定するために RETURN で終わります。

こちらは、知り合いで同じ誕生日の人たちのペアを見つけて、その友達ペアの合計数を返すシンプルなクエリです。

MATCH (n:Person)-[:knows]-(m:Person)
FILTER n.birthday = m.birthday
RETURN count(*) AS same_age_friends

このクエリは次のように実行されます。

  1. MATCH は、相互に認識 Person ノードのすべてのペアを検索します。
  2. FILTER は、両方の人が同じ誕生日を持つペアのみを保持します。
  3. RETURN は、そのようなフレンド ペアの数をカウントします。

ヒント

パターン内で WHERE 節を付け加えることで直接フィルタリングすることもできます。 例えば、MATCH (n:Person WHERE n.birthday < 19900101)は1990年以前にbirthday値を持つノードPersonつしかマッチしません。

GQL では、C スタイルの // 行コメント、SQL スタイルの -- 行コメント、および C スタイルの /* */ ブロック コメントがサポートされています。

一般的な表現

  • MATCH検索すべきグラフパターンを特定します。ここで関心のあるデータの構造を定義します。
  • LET: マッチしたデータに基づいて新しい変数や計算値を割り当て、結果に導出列を追加します。
  • FORリストを行に展開し、任意のゼロベースのオフセットまたは1ベースの順序数の位置があります。
  • CALL: 各入力行に対してインラインのサブクエリを実行し、そのサブクエリから返された列を追加します。
  • FILTER条件を適用して結果を絞り込み、条件に合わない行を削除します。
  • ORDER BY:フィルタリングされたデータをソートし、1つ以上のフィールドに基づいて出力を整理するのに役立ちます。
  • OFFSET LIMIT:返される行数を制限する—ページ付けやトップkクエリに有用です。
  • RETURN: 最終出力を指定し、結果セットに含まれるべきデータを定義し、集計を行います。
  • NEXT: 前段階から戻された列を用いて別のクエリステージを開始します。

ステートメントの連携方法

GQL文はパイプラインを形成し、各文は前の文の出力を処理します。 この逐次実行により、クエリの読み取りやデバッグが容易になります。なぜなら、実行順序が読み取り順と一致しているからです。

重要なポイント:

  • 文は実質的に連続して実行されます。
  • 各文はデータを変換し、次の文に渡します。
  • このプロセスにより、複雑なクエリを簡略化する、明確で予測可能なデータ フローが作成されます。
  • NEXT 新しいクエリステージを始めます。 次の段階では、前の RETURN 文で投影された列のみが利用可能です。
  • UNION、 UNION DISTINCT、 UNION ALL は完全なクエリブロックの結果を組み合わせます。

注

文には定義された論理順序があります。 特定の物理的な実行戦略に頼るのではなく、このデータフローに従ってクエリを書きましょう。

ステートメント構成の例

以下のGQLクエリは、名前に「Air」が入っている企業で働く最初の10人を見つけ、氏名順に並べ替え、氏名と会社名を返します。

-- Data flows: Match → Let → Filter → Order → Limit → Return
MATCH (p:Person)-[:workAt]->(c:Company)           -- Input: unit table, Output: (p, c) table
LET fullName = p.firstName || ' ' || p.lastName   -- Input: (p, c) table, Output: (p, c, fullName) table
FILTER c.name CONTAINS 'Air'                      -- Input: (p, c, fullName) table, Output: filtered table
ORDER BY fullName                                 -- Input: filtered table, Output: sorted table
LIMIT 10                                          -- Input: sorted table, Output: top 10 rows table
RETURN fullName, c.name AS companyName            -- Input: top 10 rows table
                                                  -- Output: projected (fullName, companyName) result table

このクエリは次のように実行されます。

  1. MATCH 企業で働く人を見つけます。
  2. LET は、姓と家族名を組み合わせてフルネームを作成します。
  3. FILTER 会社名に「Air」が入っている会社の従業員のみを雇用します。
  4. ORDER BY は完全な名前で並べ替えられます。
  5. LIMIT は最初の 10 件の結果を受け取ります。
  6. RETURN 氏名と会社名を返送します。

変数を使用してデータを接続する

前の例の p、 c、 fullName などの変数は、ステートメント間でデータを伝達します。 変数名を再利用すると、GQL は自動的に同じデータを参照し、強力な結合条件を作成します。 変数はバインド変数とも呼ばれます。

変数は、さまざまな方法で分類できます。

ソースをバインドする方法:

  • パターン変数 - 一致するグラフ パターンによってバインドされます
  • 標準変数 - 他の言語コンストラクトによってバインドされます

パターン変数の型:

  • 要素変数 - グラフ要素参照値へのバインド
    • ノード変数 - 個々のノードにバインドする
    • エッジ変数 - 個々のエッジにバインド
  • パス変数 - 一致したパスを表すパス値にバインドする

参照の次数:

  • シングルトン変数 - パターンから個々の要素参照値にバインドする
  • グループ変数 - 可変長パターンの要素参照値リストにバインドします。 詳細は 「集計関数」を参照してください。

実行の結果と結果

クエリを実行すると、次の要素で構成される 実行結果 が返されます。

  • 結果、通常は RETURN 文のデータを含む結果テーブルです。
  • クエリが成功したかどうかを示す状態情報。

結果テーブル

結果テーブル (存在する場合) は、クエリ実行の実際の結果です。

結果テーブルには、その列の名前と型、結果の表示に使用する推奨される列名シーケンス、テーブルの順序、 、および実際の行自体に関する情報が含まれます。

注

実行が失敗した場合、結果テーブルは実行結果に含まれません。

省略された結果

GQLはまた、データや評価結果とは無関係に行を生成しない文に対して省略結果を定義します。 省略された結果は成功完了ステータスコード 00001。

省略された結果は空の結果表とは異なります。 空のテーブルは、行を生成するクエリは評価されたものの行を生成しなかったことを意味します。 クエリAPIは、結果の種類 NOTHINGで省略された結果を表現できます。

グラフは、将来のデータ定義言語(DDL)やデータ操作言語(DML)の文サポートのために省略された結果を保存します。 現在のクエリ文は、空のテーブルを含むテーブル結果を生成します。

状態情報

クエリの実行中、プロセスはエラーや警告など、注目すべきさまざまな条件を検出します。 各条件は、実行結果の状態情報に状態オブジェクトによって記録されます。

ステータス情報は、プライマリ ステータス オブジェクトと、他のステータス オブジェクトの (空の可能性がある) リストで構成されます。 プライマリ 状態オブジェクトは常に存在し、クエリの実行が成功したか失敗したかを示します。

すべてのステータスオブジェクトには5文字の英数字コードと記録された状態の説明が含まれています。

クエリAPIは以下の主要ステータスコードを使用します:

APIステータスコード Meaning
00000 少なくとも1列で成功。
00001 結果が省略されたまま成功。 将来のDDLおよびDMLサポート用に予約されています。
01000 警告や情報提供の条件。
02000 現在、行生成クエリからは行が利用できません。
42000 ユーザーが修正可能なクエリエラーです。
50000 システムか非機密エラーか。

APIは、診断レコードの _graphaneGqlStatus メンバーにクエリエンジンが報告する標準的なGQLSTATUSを保持します。 例えば、数値オーバーフローは標準的なGQLSTATUS 22003を使い、ゼロでの割り算は 22012 を使用します。どちらも公開status.codeフィールドでは 42000 で表現されます。

Important

アプリケーションコードでは、広範な成功とエラー処理のために status.code を使いましょう。 特定のクエリ条件を区別する必要がある場合は、標準的なGQLSTATUS診断を用いてください。 説明文は変わることがあるのでテストしないでください。

さらに、ステータス オブジェクトには、基になる原因ステータス オブジェクトと、記録された条件を特徴付けた詳細情報を含む診断レコードを含めることができます。

基本的な概念とステートメント

このセクションでは、効果的な GQL クエリを記述するために必要な主要な構成要素について説明します。 各概念は、実用的なクエリ作成スキルに向けて構築されています。

グラフパターン:構造を見つける

グラフパターンは、一致するノード、辺、パスを記述します。 後の文が一致した要素を参照する必要がある場合、変数をバインドします:

MATCH (person:Person)-[employment:workAt]->(company:Company)
RETURN person.firstName, company.name, employment.workFrom

述語を、どのノードまたはエッジがパターンに参加できるかを定義した場合に、列に置きます。

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

同じ要素を2つのパターン位置に割り当てる変数を再利用します。 カンマでパターンを分けて大きなグラフ構造を構成すること。 {1,4}のような量化子を使ってエッジパターンを繰り返し、可変長の経路をマッチングします。

パスモード制御要素の再利用は、パス内でのもの:

パス モード Behavior
WALK ノードとエッジを繰り返し使用できます。 このモードが既定です。
TRAIL 繰り返しのエッジを防ぎます。
SIMPLE 共有された最初のノードと最後のノードを除き、繰り返しのノードを防いでいます。
ACYCLIC すべての繰り返しノードを防ぎます。

パスサーチプレフィックスは、どの一致するパスを返すかを制御します。 ALL はデフォルト値です。 ANY SHORTEST 各送信先-宛先ペアに対して最短経路を1つ返します:

MATCH path = ANY SHORTEST
  (source:Person WHERE source.id = 123u)-[:knows]->{1,4}(target:Person)
RETURN target.id, path_length(path) AS hopCount

インライン述語はパス選択の前にパス適格性を制約します。 文レベルの MATCH ... WHERE およびそれ以降の FILTER 演算はポストフィルターです。 この区別は結果を変え ANY SHORTEST ことがあります。

定めのノード、エッジ、パス、合成、量化子、述語配置の意味論については、 GQLグラフパターンを参照してください。 現在の経路制限については 「現在の制限」を参照してください。

コア ステートメント

GQL には、グラフ データを段階的に処理するために連携する特定のステートメントの種類が用意されています。 これらのステートメントを理解することは、効果的なクエリを構築するために不可欠です。

MATCH ステートメント

構文 :

MATCH <graph pattern>, <graph pattern>, ... [ WHERE <predicate> ]

MATCH ステートメントは入力データを受け取り、グラフ パターンを検索します。 入力変数をパターン変数と結合し、一致したすべての組み合わせを出力します。

入力変数と出力変数:

-- Input: unit table (no columns, one row)
-- Pattern variables: p, c  
-- Output: table with (p, c) columns for each person-company match
MATCH (p:Person)-[:workAt]->(c:Company)

WHERE を使用したステートメント レベルのフィルター処理:

-- Filter pattern matches
MATCH (p:Person)-[:workAt]->(c:Company) WHERE p.lastName = c.name

WHEREを使用して、すべての一致を後でフィルター処理できます。 この方法では、別の FILTER ステートメントを回避できます。 ANY SHORTESTのようなパスサーチプレフィックスの場合、文レベルのWHEREはパス選択後に適用されます。 インライン述語は代わりに、選択可能なパスを制約します。 詳細については、「 パス選択の前後に述語を置く」を参照してください。

入力変数を使用した結合:

MATCHが最初のステートメントでない場合は、入力データをパターン一致と結合します。

...
-- Input: table with 'targetCompany' column
-- Implicit join: targetCompany (equality join)
-- Output: table with (targetCompany, p, r) columns
MATCH (p:Person)-[r:workAt]->(targetCompany)

Important

グラフは基本および完全な線形文の合成をサポートし、 NEXTも含まれます。 クエリブロックは UNION、 UNION DISTINCT、 UNION ALLと組み合わせることも可能です。 EXCEPT、INTERSECT、OTHERWISEセット操作はまだサポートされていません。 詳細については、 現在の制限事項に関する記事を参照してください。

主な結合動作:

MATCHがデータ結合を処理する方法:

  • 変数の等価性: 等価一致を使用した入力変数とパターン変数の結合
  • 内部結合: パターン一致のない入力行は破棄されます。 左外部結合の動作には OPTIONAL MATCH を使用します。
  • フィルタリング順序:パターンマッチングおよびパス選択が完了した後の文レベルの WHERE フィルタ
  • パターン構成:共有変数はパターンを同じ要素に制限します。 切り離されたパターンはデカルト積を形成します。

Important

連結していないパターンは有効ですが、そのデカルト積は多くの行を作ることができます。 パターンが同じグラフ要素を参照すべき場合、共有変数を使いましょう。

共通変数でパターンを結合する:

-- Shared variable 'p' joins the two patterns
-- Output: people with both workplace and residence data
MATCH (p:Person)-[:workAt]->(c:Company), 
      (p)-[:isLocatedIn]->(city:City)

OPTIONAL MATCH ステートメント

構文 :

OPTIONAL MATCH <graph pattern> [ WHERE <predicate> ]

OPTIONAL MATCH は MATCH と同様に機能しますが、左外部結合セマンティクスを使用します。 パターンで入力行に一致するものが見つからない場合、クエリでは、一致しない変数の NULL 値を持つ行が破棄されるのではなく保持されます。

Example:

-- Find all people and, if available, their workplace
MATCH (p:Person)
OPTIONAL MATCH (p)-[:workAt]->(c:Company)
RETURN p.firstName, p.lastName, c.name AS company_name

どの会社で働いていないユーザーも、NULLのcompany_nameを使用して結果に表示されます。

ヒント

SQL OPTIONAL MATCHと同様に、特定のリレーションシップを持たないエンティティを含める場合は、LEFT JOINを使用します。

LET ステートメント

構文 :

LET <variable> = <expression>, <variable> = <expression>, ...

LET ステートメントは、計算された変数を作成し、クエリ パイプライン内でデータ変換を有効にします。

基本的な変数の作成:

MATCH (p:Person)
LET fullName = p.firstName || ' ' || p.lastName
RETURN *
LIMIT 1000

複雑な計算:

MATCH (p:Person)
LET adjustedAge = 2000 - (p.birthday / 10000),
    fullProfile = p.firstName || ' ' || p.lastName || ' (' || p.gender || ')'
RETURN *
LIMIT 1000

主な動作:

  • クエリ エンジンは、すべての入力行の式を評価します。
  • 結果は出力テーブルの新しい列になります。
  • 変数は、前のステートメントの既存の変数のみを参照できます。
  • 1つの LET 文内の複数の割り当ては同じ入力スコープを使うため、割り当てはその文から別の割り当てを参照することはできません。

FOR ステートメント

構文 :

FOR <variable> IN <list_expression>
  [ WITH OFFSET <offset_variable> | WITH ORDINALITY <ordinality_variable> ]

FOR文はリストを行に展開します。 各入力行に対して、各リスト要素に対して1行の出力を出力し、その要素を指定された変数に割り当てます。 入力行の他の変数は引き続き利用可能です。

WITH OFFSETを用いてゼロベースのインデックスを、WITH ORDINALITYを用いて1ベースの位置をバインドします。

LET cities = ['Seattle', 'London', 'Tokyo']
FOR city IN cities WITH ORDINALITY position
RETURN city, position

このクエリは各都市ごとに1行を返します。 position値は1、2、3です。 WITH ORDINALITY positionをWITH OFFSET positionに置き換えると、値は0、1、2となります。

ソース式はリストに評価されなければなりません。 非リスト値だとクエリが失敗します。

CALL ステートメント

CALLを使って、各入力行に対してインラインのサブクエリを実行します:

CALL {
  <query statements>
  RETURN <columns>
}

すでにスコープにある変数はサブクエリ内で暗黙的に利用可能です。 サブクエリ内で作成された変数のうち、外部で利用可能なのは最終的な RETURN 文の列のみです。 サブクエリ内で作成されたが返されなかった変数はローカルのままです。

以下の相関サブクエリは、各人物の雇用主数を計算します。

MATCH (p:Person)
CALL {
  MATCH (p)-[:workAt]->(company:Company)
  RETURN count(*) AS employerCount
}
RETURN p.firstName, p.lastName, employerCount
ORDER BY employerCount DESC

通常の CALL は依存する内結合のように振る舞います。 サブクエリが返す1行ごとに1行の出力行を生成します。 もしサブクエリが行を返さなければ、対応する外側の行は返されません。 複数の行を返す場合、外側の行は各サブクエリ行に対して一度ずつ表示されます。

前の count(*) 例は、グループ化されていない集約を使用しているため、常に1つのサブクエリ行を返します。 したがって、対応する雇用主がいない人は0employerCountとなります。

従属左のジョインとして使う OPTIONAL CALL 。 サブクエリが行を返さない場合、外側の行を1行保持し、返されるサブクエリの列を NULLに設定します。 サブクエリが複数の行を返す場合、各サブクエロイション行に対して1行の出力を生成します。

MATCH (p:Person)
OPTIONAL CALL {
  MATCH (p)-[:workAt]->(company:Company)
  RETURN company.name AS companyName
}
RETURN p.firstName, p.lastName, companyName

インライン CALL サブクエリをネストできます。 ネストされたサブクエリは、その囲むクエリスコープから変数を参照することができます。

Important

各インラインのボディ CALL 最後に RETURNを付けます。 グラフは名前付きプロシージャコールや CALL (p) { ... }のような明示的な変数インポートリストをサポートしていません。

FILTER ステートメント

構文 :

FILTER [ WHERE ] <predicate>

FILTER ステートメントを使用すると、クエリ パイプラインを通過するデータを正確に制御できます。

基本的なフィルター処理:

MATCH (p:Person)
FILTER p.birthday < 19980101 AND p.gender = 'female'
RETURN *

複雑な論理条件:

MATCH (p:Person)
FILTER (p.gender = 'male' AND p.birthday < 19940101) 
  OR (p.gender = 'female' AND p.birthday < 19990101)
  OR p.browserUsed = 'Edge'
RETURN *

Null 対応のフィルター処理パターン:

null 値を安全に処理するには、次のパターンを使用します。

  • 値を確認する: p.firstName IS NOT NULL - 名が付けられます
  • データの検証: p.id > 0 - 有効な ID
  • 不足しているデータを処理する: NOT coalesce(p.locationIP, '10.x.x.x') STARTS WITH '10.x.x.x' - ローカル ネットワークから接続しませんでした
  • 条件の組み合わせ: 複雑なロジックの明示的な null チェックで AND/OR を使用する

注意事項

null 値を含む条件は UNKNOWNを返し、それらの行を除外します。 null を含むロジックが必要な場合は、明示的な IS NULL チェックを使用します。

ORDER BY ステートメント

構文 :

ORDER BY <expression> [ ASC | DESC ] [ NULLS FIRST | NULLS LAST ],
         <expression> [ ASC | DESC ] [ NULLS FIRST | NULLS LAST ], ...

計算式を使用した複数レベルの並べ替え:

MATCH (p:Person)
RETURN *
ORDER BY p.firstName DESC,               -- Primary: by first name (Z-A)
         p.birthday ASC,                 -- Secondary: by age (oldest first)
         p.id DESC                       -- Tertiary: by ID (highest first)

並べ替え時の NULL 処理:

MATCH (p:Person)
RETURN p.firstName, p.birthday
ORDER BY p.birthday DESC NULLS LAST, p.firstName ASC

並べ替え動作の詳細:

ORDER BYのしくみを理解する:

  • クエリ エンジンは各行の式を評価し、結果によって行の順序が決まります。
  • 複数の並べ替えキーによって階層的な順序 (プライマリ、セカンダリ、3 次など) が作成されます。
  • NULLS FIRST null値の前にnull値を置きます。 NULLS LAST 非nullの値の後に配置します。
  • ヌル配置はソート方向に依存しません。 ヌルオーダーを指定していない場合、 NULLS LAST が ASC と DESCの両方のデフォルトとなります。
  • ASC (昇順) は既定の順序であり、 DESC (降順) を明示的に指定する必要があります。
  • 格納されたプロパティだけでなく、計算値で並べ替えることができます。
ソート仕様 結果的な順序
ASC または ASC NULLS LAST 非nullの値が昇順で続き、その後にnull値が続きます。
ASC NULLS FIRST null 値の後に昇順で非null値が続きます。
DESC または DESC NULLS LAST 降順の非null値の後にnull値が続きます。
DESC NULLS FIRST nullの値の後に降順のnullでない値が続きます。

注意事項

確立された並べ替え順序を確認できるのは、ORDER BYのステートメントだけです。 したがって、 ORDER BY 後に RETURN * が続く場合、順序付けされた結果は生成されません。

比べる:

MATCH (a:Person)-[r:knows]->(b:Person)
LET aName = a.firstName || ' ' || a.lastName
LET bName = b.firstName || ' ' || b.lastName
ORDER BY r.creationDate DESC
/* intermediary result _IS_ guaranteed to be ordered here */
RETURN aName, bName, r.creationDate AS since
/* final result _IS_ _NOT_ guaranteed to be ordered here  */

次と置き換えます。

MATCH (a:Person)-[r:knows]->(b:Person)
LET aName = a.firstName || ' ' || a.lastName
LET bName = b.firstName || ' ' || b.lastName
/* intermediary result _IS_ _NOT_ guaranteed to be ordered here */
RETURN aName, bName, r.creationDate AS since
ORDER BY r.creationDate DESC
/* final result _IS_ guaranteed to be ordered here              */

この違いは、"Top-k" クエリに直ちに影響します。 LIMIT は常に、目的の並べ替え順序を確立する ORDER BY ステートメントに従う必要があります。

OFFSET と LIMIT のステートメント

構文 :

  OFFSET <offset> [ LIMIT <limit> ]
| LIMIT <limit>

一般的なパターン:

-- Basic top-N query
MATCH (p:Person)
RETURN *
ORDER BY p.id DESC
LIMIT 10                                 -- Top 10 by ID

Important

予測可能な改ページ位置の結果を得るには、ORDER BYする前に常にOFFSETを使用し、LIMITして、クエリ間で一貫した行順序を確保します。

RETURN: 基本的な結果予測

構文 :

RETURN [ DISTINCT ] <expression> [ AS <alias> ], <expression> [ AS <alias> ], ...
[ ORDER BY <expression> [ ASC | DESC ] [ NULLS FIRST | NULLS LAST ], ... ]
[ OFFSET <offset> ]
[ LIMIT <limit> ]

RETURN ステートメントは、結果テーブルに表示されるデータを指定して、クエリの最終的な出力を生成します。

基本的な出力:

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName || ' ' || p.lastName AS name, 
       p.birthday, 
       c.name

わかりやすくするためにエイリアスを使用する:

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName AS first_name, 
       p.lastName AS last_name,
       c.name AS company_name

並べ替えと top-k を組み合わせる:

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName || ' ' || p.lastName AS name, 
       p.birthday AS birth_year, 
       c.name AS company
ORDER BY birth_year ASC
LIMIT 10

DISTINCT を使用した重複処理:

-- Remove duplicate combinations
MATCH (p:Person)-[:workAt]->(c:Company)
RETURN DISTINCT p.gender, p.browserUsed, p.birthday AS birth_year
ORDER BY p.gender, p.browserUsed, birth_year

集計と組み合わせる:

MATCH (p:Person)-[:workAt]->(c:Company)
RETURN count(DISTINCT p) AS employee_count

RETURN GROUP BY: グループ化された結果プロジェクション

構文 :

RETURN [ DISTINCT ] <expression> [ AS <alias> ], <expression> [ AS <alias> ], ...
GROUP BY <variable>, <variable>, ...
[ ORDER BY <expression> [ ASC | DESC ], <expression> [ ASC | DESC ], ... ]
[ OFFSET <offset> ]
[ LIMIT <limit> ]

GROUP BYを使用して、共有値で行をグループ化し、各グループ内の集計関数を計算します。

集計を使用した基本的なグループ化:

MATCH (p:Person)-[:workAt]->(c:Company)
LET companyId = c.id, companyName = c.name
RETURN companyId,
       companyName,
       count(*) AS employeeCount,
       avg(p.birthday) AS avg_birth_year
GROUP BY companyId, companyName
ORDER BY employeeCount DESC

複数列のグループ化:

MATCH (p:Person)
LET gender = p.gender
LET browser = p.browserUsed
RETURN gender,
       browser,
       count(*) AS person_count,
       avg(p.birthday) AS avg_birth_year,
       min(p.creationDate) AS first_joined,
       max(p.id) AS highest_id
GROUP BY gender, browser
ORDER BY avg_birth_year DESC
LIMIT 10

注

可変長パターン上の水平集約については、 集約関数を参照してください。

値と値の型

GQLの値は、ブール値、文字列値、数値値、時間値、リスト値、ノード値、エッジ値、パス値、ヌル値、そして何もない値が含まれます。 型は指定しない限り無効化 NOT NULL。 プロパティは、クエリ値システムのサポート部分を使用します。

RETURN 42 AS integerValue,
       'Alice' AS stringValue,
       TRUE AS booleanValue,
       [1, 2, 3] AS listValue

帰無検定との比較は UNKNOWN評価され、帰無検定には IS NULL と IS NOT NULL を用います。 数値演算は、互換性のある数値型間で暗黙の変換を適用できます。

注

すべてのGQLの値タイプがすべてのグラフコンテキストでサポートされているわけではありません。 現在のプロパティおよびクエリの制限については、 データ型を参照してください。

リテラル構文、比較挙動、型変換、型階層については、 GQLの値および値型を参照してください。

Expressions

式は値を計算、比較、集約、変換します。 一般的な形式には、プロパティ参照、算術演算子や論理演算子、述語、関数呼び出し、単純 CASE 式、サブクエリなどがあります。

MATCH (person:Person)
FILTER person.birthday < 19900101
RETURN person.firstName,
       CASE person.gender
         WHEN 'female' THEN 'F'
         WHEN 'male' THEN 'M'
         ELSE 'Other'
       END AS genderCode

GQLは3値論理を用いており、ブール式は TRUE、 FALSE、または UNKNOWNに評価できます。 FILTERは述語がTRUEされる行のみを保持します。

COUNT、SUM、AVG、MIN、MAXなどの集約関数は行をまとめます。 ALL、ANY、NONE、SINGLE などのリスト述語は、リスト要素に対して述語を評価します。 プロシージャフォーム EXISTS サブクエリは、ネストされたクエリが行を返すかどうかをテストします。

完全な演算子、述語、集約、関数の挙動については、 GQL式、述語、関数を参照してください。 タスク指向のフィルタリングおよびグルーピングの例については、「 グラフデータのフィルタリングと集計」を参照してください。

高度なクエリ手法

このセクションでは、複雑で効率的なグラフ クエリを構築するための高度なパターンと手法について説明します。 これらのパターンは、強力な分析クエリを作成するのに役立つ基本的なステートメントの使用を超えています。

複雑な複数ステートメント構成

Important

Graph では、基本的な線形ステートメントと完全な線形ステートメント構成がサポートされています。 EXCEPT、INTERSECT、OTHERWISEセット操作はまだサポートされていません。 詳細については、 現在の制限事項に関する記事を参照してください。

高度なグラフ クエリでは、複雑なクエリを効率的に作成する方法を理解することが重要です。

UNION と UNION ALL

UNION、UNION DISTINCT、またはUNION ALLを使って、2つ以上の線形クエリブロックの結果を組み合わせることができます:

<query block>
UNION [ DISTINCT | ALL ]
<query block>
-- Combine results from two separate pattern matches
MATCH (p:Person)-[:workAt]->(c:Company)
RETURN p.firstName AS name, c.name AS affiliation
UNION DISTINCT
MATCH (p:Person)-[:studyAt]->(u:University)
RETURN p.firstName AS name, u.name AS affiliation

裸 UNION は UNION DISTINCTに相当し、どちらも重複した行を削除します。 UNION ALL では、重複を含むすべての行が保持されます。

各クエリブロックは同じ列名の集合を返さなければなりません。 列の順序はブロックごとに異なり、データ型は互換性がある必要があります。

NEXT

NEXTを使って、前の段階から返されたテーブルに対して別のクエリステージを実行します:

<query stage>
RETURN <columns>
NEXT
<query stage>

次のクエリは従業員とその会社を見つけ、返された従業員ノードを別のパターンマッチで使用します。

MATCH (person:Person)-[:workAt]->(company:Company)
RETURN person, company.name AS companyName
NEXT
MATCH (person)-[:isLocatedIn]->(city:City)
RETURN person.firstName AS employee, companyName, city.name AS city

NEXT以降は前の段階で返された列のみがスコープに含まれます。 複数の NEXT 区切りを使って、より長いクエリ段階のシーケンスを作成できます。

どちらの段階でもクエリブロックのユニオンを含めることができます。 ユニオンは、その段階の出力が NEXT 境界を越える前に段階内で評価されます。 A、B、Cがクエリブロックを表す場合、グループA UNION B NEXT C(A UNION B) NEXT C、A NEXT B UNION CグループをA NEXT (B UNION C)とします。

条件付きステートメント

条件文を使って、各入り行を述語が TRUEに評価される最初の分岐にルーティングします。

WHEN <predicate> THEN <linear query statement or { query statements }>
[ WHEN <predicate> THEN <linear query statement or { query statements }> ... ]
[ ELSE <linear query statement or { query statements }> ]

前のクエリ段階の行をルーティングするには、必要な列を返し、条件文の前に NEXT を用います。

MATCH (p:Person)
RETURN p.firstName AS name, p.birthday AS birthday
NEXT
WHEN birthday < 19800101u THEN
  RETURN name, 'Before 1980' AS era
WHEN birthday < 20000101u THEN
  RETURN name, '1980-1999' AS era
ELSE
  RETURN name, '2000 or later' AS era

各 WHEN 述語はブール値でなければなりません。 クエリエンジンは各入力行に対して述語を順番に評価します。 評価が FALSE または UNKNOWN に評価される述語は、その枝を選択しません。 述語が評価されて TRUEに終わった後は、その後の述語や選択されなかった分岐体は評価されません。 どの述語も TRUE に評価せず、 ELSEもなければ、入力行は返されません。

述語や分岐ボディは、前の段階の列を参照することができます。 分岐は一つの線形文であったり、括弧で囲まれたネストされた手続きであったりします。 複数の段階や文が必要な場合は、ネスト手続きを用いてください。例えば CALL:

MATCH (p:Person)
RETURN p, p.firstName AS name
NEXT
WHEN p.gender = 'female' THEN {
  CALL {
    MATCH (p)-[:knows]->(friend:Person)
    RETURN count(*) AS friendCount
  }
  RETURN name, friendCount
}
ELSE
  RETURN name, 0u AS friendCount

各支部には独自の地域範囲があります。 兄弟枝は他の枝によって作成された変数を認識せず、条件文の後に続くのは選択した枝の最終的な RETURN の列だけです。 すべてのブランチは同じ列名を返し、対応する結果型も互換性がある必要があります。 クエリエンジンは互換性のある型を共通の出力型に強制的に割り当てます。 返される分岐列は、入ってくる列と同じ名前を使用できます。分岐値は条件付き出力の入り値を置き換えます。

条件文は CASE 式とは異なります。 グラフは単純な CASE <expression> WHEN <value>をサポートしていますが、 CASE WHEN <predicate> 式の検索はできません。 詳細は 条件付き表現を参照してください。

可変範囲と高度なフロー制御

変数はクエリ ステートメント間でデータを接続し、複雑なグラフ トラバーサルを有効にします。 高度なスコープ 規則を理解することは、高度なマルチステートメント クエリを記述するのに役立ちます。

変数バインドとスコープ パターン

-- Variables flow forward through subsequent statements 
MATCH (p:Person)                                    -- Bind p 
LET fullName = p.firstName || ' ' || p.lastName     -- Bind concatenation of p.firstName and p.lastName as fullName
FILTER fullName CONTAINS 'Smith'                    -- Filter for fullNames with “Smith” substring (p is still bound)
RETURN p.id, fullName                               -- Only return p.id and fullName (p is dropped from scope) 

ステートメント間の結合に対する変数の再利用

-- Multi-statement joins using variable reuse
MATCH (p:Person)-[:workAt]->(:Company)          -- Find people with jobs
MATCH (p)-[:isLocatedIn]->(:City)               -- Same p: people with both job and residence
MATCH (p)-[:knows]->(friend:Person)             -- Same p: their social connections
RETURN *

重大なスコープの規則と制限事項

-- ✅ Backward references work
MATCH (p:Person)
LET adult = p.birthday < 20061231  -- Can reference p from previous statement
RETURN *

-- ❌ Forward references don't work  
LET adult = p.birthday < 20061231  -- Error: p not yet defined
MATCH (p:Person)
RETURN *

-- ❌ Variables in same LET statement can't reference each other
MATCH (p:Person)
LET name = p.firstName || ' ' || p.lastName,
    greeting = 'Hello, ' || name     -- Error: name not visible yet
RETURN *

-- ✅ Use separate statements for dependent variables
MATCH (p:Person)
LET name = p.firstName || ' ' || p.lastName
LET greeting = 'Hello, ' || name     -- Works: name now available
RETURN *

複雑なクエリでの変数の可視性

-- Variables remain visible until overridden or query ends
MATCH (p:Person)                     -- p available from here
LET gender = p.gender                -- gender available from here  
MATCH (p)-[:knows]->(e:Person)       -- p still refers to original person
                                     -- e is a new variable for the friend
RETURN p.firstName AS manager, e.firstName AS friend, gender

注意事項

グラフ パターンを除き、同じステートメント内の変数は相互に参照できません。 従属変数を作成する場合は、個別のステートメントを使用します。

集約行とパス要素

GQLは2つの集約コンテキストをサポートしています:

  • 垂直集約は 入力行をまとめ、オプションで GROUP BY 変数で分割されます。
  • 水平集約は 、1つのマッチングされた経路内で可変長のエッジパターンで囲まれたグループリストを要約します。
MATCH (person:Person)-[:workAt]->(company:Company)
LET companyId = company.id, companyName = company.name
RETURN companyId, companyName, count(*) AS employeeCount
GROUP BY companyId, companyName
MATCH (:Person)-[connections:knows]->{1,4}(:Person)
RETURN count(connections) AS pathLength

グループ化されたクエリ、集計固有のフィルター、コレクション集約、条件付きルーティングについては 、「フィルターおよび集計グラフデータ」を参照してください。 完全な集計結果ルールについては、 集計関数を参照してください。

nullとクエリエラーの処理

欠損値の扱いが必要な場合は明示的なnullテストを使用します:

MATCH (person:Person)
FILTER person.browserUsed IS NULL
RETURN person.firstName

nullとの比較は UNKNOWNに評価されますが、 FILTER はこれを保持しません。 バックアップが必要なときに coalesce() を使いましょう。

クエリ結果には、成功状況情報、警告、データなしの状態、ユーザー修正可能なエラー、システムエラーが含まれます。 広範な制御フローにはパブリックステータスコードを、特定の状態には標準的なGQLSTATUS診断を用いましょう。 実行結果およびGQLステータスコードの参照を参照してください。

予約語

GQL は、変数、プロパティ名、ラベル名などの識別子として使用できない特定のキーワードを予約します。 完全な一覧については、 GQL 予約語のリファレンス を参照してください。

予約語を識別子として使用する必要がある場合は、バッククォーク ( `match`、 `return`) でエスケープします。

予約語をエスケープしないようにするには、次の名前付け規則を使用します。

  • 単一単語識別子の場合は、アンダースコアを追加します。 :Product_
  • 複数単語の識別子の場合は、camelCase または PascalCase を使用します。 :MyEntity、 :hasAttribute、 textColor

次のステップ