グラフ表の形状

目的

グラフ表の形状は、パターン一致の結果を表形式に変換する方法を定義します。これは、graph_table_rows_clause句とgraph_table_columns_clause句によって実行します。

構文

graph_table_shape::=

COLUMNS句

目的

COLUMNS句を使用すると、グラフ・パターン一致の結果を頂点やエッジなどのグラフ・オブジェクトではなく通常のデータ値のみが含まれる通常の表に変換する投影を定義できます。

構文

graph_table_columns_clause::=

graph_table_column_definition::=

all_properties_reference::=

element_reference::=

セマンティクス

構文的には、COLUMNS句はキーワードCOLUMNSで始まり、その後に左カッコ、1つ以上のgraph_table_column_definitionのカンマ区切りリストおよび右カッコが続きます。

graph_table_column_definitionは、次のいずれかを定義します。

  • 任意の値式を使用した単一の出力列。値式には、頂点とエッジのプロパティ値にアクセスするなど、グラフ・パターンの頂点とエッジへの参照を含めることができます。オプションの別名AS column_nameは、列の名前を指定します。別名は、値式がプロパティ参照の場合にのみ省略でき、その場合、別名はデフォルトでプロパティ名に設定されます。

  • 要素タイプ(頂点またはエッジ)および要素に指定されたラベル式に基づいて、すべての有効なプロパティのセットに展開されるall_properties_reference。プロパティのセットとは、ラベル式を満たすラベルが少なくとも1つある表に属する頂点(またはエッジ)ラベルのプロパティを結合したものです。これらの照合表の一部でプロパティが定義されているが、他の表では定義されていない場合は、プロパティを定義しない表に対してNULL値が返されます。

オプションの別名AS column_nameは、列の名前を指定します。別名は、値式がプロパティ参照の場合にのみ省略でき、その場合、別名はデフォルトでプロパティ名に設定されます。

例1

次の例では、各人の名前と、メートル単位の高さに3.281を乗算して高さ(フィート)を戻します:

SELECT *
FROM GRAPH_TABLE ( students_graph
  MATCH (n IS person|person_ht)
  COLUMNS (n.name, n.height * 3.281 AS height_in_feet)
)
ORDER BY name;

前述の問合せでは、COLUMNS句によって2つの列が定義されています。n.namen.name AS nameの略です。

結果は次のとおりです。

NAME       HEIGHT_IN_FEET
---------- --------------
Alice              5.5777

例2

次の問合せは、2人のP1P2の間のすべてのFRIENDSエッジに一致し、すべてのプロパティがP1.*E.*を参照して、頂点P1のすべてのプロパティおよびエッジEのすべてのプロパティを取得します。

SELECT *
FROM GRAPH_TABLE ( students_graph
  MATCH (p1 IS person) -[e IS friends]-> (p2 IS person)
  COLUMNS ( p1.*, p2.name AS p2_name, e.* )
)
ORDER BY 1, 2, 3, 4, 5;

結果は次のとおりです。

PERSON_ID NAME DOB       HEIGHT P2_NAME FRIENDSHIP_ID MEETING_D
--------- ---- --------- ------ ------- ------------- ---------
        1 John 13-JUN-63   1.8   Bob 	        1 01-SEP-00
        2 Mary 25-SEP-82   1.65  Alice              2 19-SEP-00
        2 Mary 25-SEP-82   1.65  John               3 19-SEP-00
        3 Bob  11-MAR-66   1.75  Mary               4 10-JUL-01

P1.*の結果には、ラベルPERSONのプロパティPERSON_IDNAMEおよびDOBと、ラベルPERSON_HTのプロパティHEIGHTが含まれます。さらに、E.*の結果には、ラベルFRIENDSのプロパティFRIENDSHIP_IDおよびMEETING_DATEが含まれます。

例3

次の問合せは、グラフ内のすべての頂点に一致し、すべてのプロパティを取得します。

SELECT *
FROM GRAPH_TABLE ( students_graph
  MATCH (v)
  COLUMNS ( v.* )
)
ORDER BY 1, 2, 3, 4, 5;

結果は次のとおりです。

 PERSON_ID NAME       DOB       HEIGHT     ID
---------- ---------- --------- ---------- ----------
         1 John       13-JUN-63        1.8
         2 Mary       25-SEP-82       1.65
         3 Bob        11-MAR-66       1.75
         4 Alice      01-FEB-87        1.7
           ABC                                      1
           XYZ                                      2

PERSON頂点にはIDプロパティがないため、NULL値(空の文字列)が返されます。同様に、UNIVERSITY頂点には PERSON_IDDOBおよびHEIGHTプロパティがないため、NULL値(空の文字列)が再度返されます。

Rows句

目的

GRAPH_TABLE rows句は、グラフ・パターンに対する一致の数、またはこのような一致での頂点やステップの数に基づいて、GRAPH_TABLEから返される行数を指定するために使用します。

構文

graph_table_rows_clause::=

one_row_per_iteration::=

graph_table_rows_clause

  • ONE ROW PER MATCH (デフォルト)により、グラフ・パターンとの一致が1行ずつ返されるようにすることを指定します。

  • one_row_per_iterationにより、1つ以上のイテレータ変数を宣言し、反復ごとに1行が返されるようにします。具体的には、次のとおりです。

    • ONE ROW PER VERTEXにより、1つのイテレータ頂点変数を宣言します。これにより、パス内の各頂点が反復処理され、そのイテレータ変数が、別の反復での別の頂点にバインドされます。パスごとに、パス内の頂点と同じ数の行が作成されます。たとえば、パターンがパス2つ(1つは頂点3つ、もう1つは頂点5つ)に一致する場合は、合計8行が返されます。

    • ONE ROW PER STEPにより、イテレータ頂点変数、イテレータ・エッジ変数およびもう1つのイテレータ頂点変数を宣言します。これにより、様々なパスのステップが反復処理されます。1つのステップは、頂点-エッジ-頂点という3つの要素からなります。パスが空でなく、1つ以上のエッジと2つの頂点が含まれている場合は、エッジと同じ数のステップがあり、各反復によってそれらのイテレータ変数が次のエッジ、およびそのパス内のソースと宛先にバインドされます。ただし、パスが空であり、1つの頂点のみで構成されている場合、そのパスには1つのステップがあり、最初のイテレータ頂点変数がその頂点にバインドされますが、イテレータ・エッジ変数と2つ目のイテレータ頂点変数はどのグラフ要素にもバインドされません。

all_properties_referenceにイテレータ変数への参照が含まれている場合は、それが、そのイテレータ変数のタイプに応じて、すべての頂点プロパティまで、またはグラフ内のすべてのエッジ・プロパティまで広がります。なお、イテレータ変数のプロパティを広げるときに、グラフ・パターンでの要素のラベル式は考慮されません。

COLUMNSgraph-table-shape.html#GUID-1C95A975-EEC8-44B0-AAE4-655B69F528E2__GUID-252808EF-CF93-420C-8DE9-73E5625B4577 all_properties_clauseを参照してください。

制限事項

graph_table_rows_clause句には、次の制限事項があります:

  • one_row_per_iterationを使用する場合、グラフ・パターンは、1つのパス・パターンのみで構成する必要があります。

  • イテレータ要素変数は、多数重ねて宣言できません。つまり、イテレータ変数を、そのグラフ・パターンで宣言されている要素変数や、別のイテレータ変数と同じ名前で宣言することはできません。

  • イテレータ変数は、COLUMNS句でのみ参照でき、グラフ・パターンにおいてや、グラフ・パターンのWHERE句においては参照できません。

例1

次の問合せでは、Johnという名前の人物から開始して、長さが0から3までの、すべての友人パスを見つけます。頂点ごとに1行を出力します。

SELECT *
FROM GRAPH_TABLE ( students_graph
       MATCH (n IS person) -[e1 IS friends]->{0,3} (IS person)
       WHERE n.name = 'John'
       ONE ROW PER VERTEX (v)
       COLUMNS (
        LISTAGG(e1.friendship_id, ', ') AS friendship_ids,
        v.name)
     );

結果は、次のとおりです:

FRIENDSHIP_IDS       NAME
-------------------- ---------------
                     John
1                    John
1                    Bob
1, 4                 John
1, 4                 Bob
1, 4                 Mary
1, 4, 3              John
1, 4, 3              Bob
1, 4, 3              Mary
1, 4, 3              John
1, 4, 2              John
1, 4, 2              Bob
1, 4, 2              Mary
1, 4, 2              Alice

上の結果は、一致した5つのパスからのデータを示しています。

  • 空のパス(friendship_idsがゼロ)には、Johnという名前の1人が含まれています。

  • friendship_idsが1のパスには、JohnとBobという名前の2人が含まれています。

  • friendship_idsが1、4のパスには、John、BobおよびMaryという名前の3人が含まれています。

  • friendship_idsが1、4、3のパスには、John、Bob、MaryおよびJohnという名前の4人が含まれています(これは循環です)。

  • friendship_idsが1、4、2のパスには、John、Bob、MaryおよびAliceという名前の4人が含まれています。

例2

次の問合せでは、もう一度、Johnという名前の人物から開始して、長さが0から3までの、すべての友人パスを見つけます。今度は、ステップごとに1行を出力します。

SELECT *
FROM GRAPH_TABLE ( students_graph
       MATCH (n IS person) -[e1 IS friends]->{0,3} (IS person)
       WHERE n.name = 'John'
       ONE ROW PER STEP (src, e2, dst)
       COLUMNS (
         LISTAGG(e1.friendship_id, ', ') AS friendship_ids,
         src.name AS src_name,
         e2.friendship_id,
         dst.name AS dst_name)
     );

結果は、次のとおりです:

FRIENDSHIP_IDS       SRC_NAME   FRIENDSHIP_ID DST_NAME
-------------------- ---------- ------------- ----------
                     John
1                    John       1             Bob
1, 4                 John       1             Bob
1, 4                 Bob        4             Mary
1, 4, 3              John       1             Bob
1, 4, 3              Bob        4             Mary
1, 4, 3              Mary       3             John
1, 4, 2              John       1             Bob
1, 4, 2              Bob        4             Mary
1, 4, 2              Mary       2             Alice

上の結果は、一致した5つのパスからのデータを示しています。

  • 空のパス(friendship_idsなし)には単一のステップがあり、そのステップでは、イテレータ頂点変数srcはJohnという名前の人物に対応する頂点にバインドされるが、イテレータ・エッジ変数e2とイテレータ頂点変数dstはバインドされないため、FRIENDSHIP_IDDST_NAMEがNULL値になります。

  • friendship_idsが1のパスには、1つのエッジがあるため、1つのステップがあります。このステップでは、イテレータ頂点変数srcが、Johnに対応する頂点にバインドされ、イテレータ・エッジ変数e2が、friendship_idsが1のエッジにバインドされ、イテレータ頂点変数dstが、Bobに対応する頂点にバインドされます。

  • friendship_idsが1、4のパスには、2つのエッジがあるため、2つのステップがあります。

  • friendship_idsが1、4、3のパスには、3つのエッジがあるため、3つのステップがあります。

  • friendship_idsが1、4、2のパスにも、3つのエッジがあるため、3つのステップがあります。

例3

次の問合せでは、ABC大学とXYZ大学の間のパスを照合し、パスが開始student_ofエッジ、1人または2人の交友関係エッジ、および終了student_ofエッジの順で構成されるようにします。この問合せは頂点ごとに1行を返し、行ごとに一致番号、要素番号、頂点のタイプ(personまたはuniversity)および大学または個人の名前を返します。

SELECT *
FROM GRAPH_TABLE ( students_graph
       MATCH (u1 IS university)
               <-[IS student_of]- (p1 IS person)
               -[IS friends]-{1,2} (p2 IS person)
               -[IS student_of]-> (u2 IS university)
       WHERE u1.name = 'ABC' AND u2.name = 'XYZ'
       ONE ROW PER VERTEX (v)
       COLUMNS (MATCHNUM() AS matchnum,
                ELEMENT_NUMBER(v) AS element_number,
                CASE WHEN v.person_id IS NOT NULL
                  THEN 'person'
                  ELSE 'university'
                  END AS label,
                v.name))
ORDER BY matchnum, element_number;

結果は、次のとおりです:

MATCHNUM ELEMENT_NUMBER        LABEL       NAME
---------- -------------- ---------- ----------
         1              1 university         ABC
         1              3 person             John
         1              5 person             Mary
         1              7 university         XYZ
         2              1 university         ABC
         2              3 person             Bob
         2              5 person             John
         2              7 person             Mary
         2              9 university         XYZ
         3              1 university         ABC
         3              3 person             Bob
         3              5 person             Mary
         3              7 university         XYZ
         4              1 university         ABC
         4              3 person             John
         4              5 person             Mary
         4              7 person             Alice
         4              9 university         XYZ
         6              1 university         ABC
         6              3 person             John
         6              5 person             Bob
         6              7 person             Mary
         6              9 university         XYZ
         8              1 university         ABC
         8              3 person             Bob
         8              5 person             Mary
         8              7 person             Alice
         8              9 university         XYZ

合計6つのパスが一致番号12346および8と一致しています。各パスには、最初の頂点としてABC大学、最後の頂点としてXYZ 大学があります。さらに、一致番号1および3のパスには2つのpersonの頂点が含まれ、他のパス(一致番号246および8)には3つのpersonの頂点が含まれています。