6.8.3.2 可変長パス問合せのネスト解除

可変長パス問合せ(SHORTESTパスやCHEAPESTパスなど)のネストを解除して、パスに沿った頂点またはエッジごとに個別の行を取得できます。

次のオプションのいずれかを使用して、パス集計をネスト解除できます。
  • ONE ROW PER MATCH (デフォルト・オプション)
  • ONE ROW PER VERTEX(vertex_variable)
  • ONE ROW PER STEP(edge_source_variable,edge_variable,edge_destination_variable)

たとえば、次のPGQL問合せではONE ROW PER STEPオプションを使用します。

SELECT  v1.ACCT_ID AS src_no, k.TXN_AMOUNT, v2.ACCT_ID AS dest_no 
FROM MATCH ALL SHORTEST (a:Accounts) -[e:transfers]->+ (b:Accounts)
ONE ROW PER STEP( v1,k,v2 )
WHERE a.ACCT_ID = 284 AND b.ACCT_ID = 616

ONE ROW PER STEPオプションは、最小ホップが0より大きいパスのみをサポートするため、*修飾子はこのオプションでサポートされていないことに注意してください。

実行すると、前述の問合せでは、対応するソース頂点および宛先頂点によってバインドされているパス上のエッジごとに1行を取得します。

+-------------------------------+
| src_no | TXN_AMOUNT | dest_no |
+-------------------------------+
| 744    | 1000.0     | 616     |
| 772    | 1000.0     | 744     |
| 284    | 1000.0     | 772     |
| 744    | 1000.0     | 616     |
| 772    | 1500.0     | 744     |
| 284    | 1000.0     | 772     |
+-------------------------------+

グラフ・ビジュアライゼーション・ツールを使用して、パスに沿ってONE ROW PER STEPを使用してエッジを視覚化することもできます。

図6-1 可変長パス問合せのネスト解除の視覚化

図6-1の説明を次に示します
「図6-1 可変長パス問合せのネスト解除の視覚化」の説明

ONE ROW PER VERTEXオプションを指定した問合せの例を次に示します。

SELECT k.acct_id AS id, k.acct_name AS name
FROM MATCH ANY SHORTEST (a:Accounts) ((src:Accounts)-[e:transfers]->){1,3}(b:Accounts)
ONE ROW PER VERTEX(k)
WHERE a.acct_id=284 AND b.acct_id=616

実行時には、前述の問合せはパスに沿って頂点ごとに1行を取得します。

+----------------+
| id  | name     |
+----------------+
| 616 | Account4 |
| 744 | Account3 |
| 772 | Account2 |
| 284 | Account1 |
+---------------+

再帰的なパスのネスト解除問合せ用の組込み関数のサポート

PGQLは、次の2つの組込み関数をサポートしており、これらはパスのネスト解除オプション(ONE ROW PER VERTEXONE ROW PER STEPまたはONE ROW PER MATCH)のいずれかと組み合せて使用できます。

  • MATCH_NUMBER(k): ネスト解除されたパスごとに一意のパス単位の識別子を戻します(つまり、2つの行の元が同じパスである場合、それらのMATCH_NUMBER(k)は同じです)。
  • ELEMENT_NUMBER(k): パスに沿って頂点またはエッジの要素番号を戻します。左端の頂点には1、2番目には3、その次には5のように、頂点には奇数の番号が付けられます。左端のエッジには2、次のエッジには4のように、エッジには偶数の番号が割り当てられます。

たとえば、次のPGQL問合せでは、ONE ROW PER VERTEXオプションを指定してMATCH_NUMBER(k)およびELEMENT_NUMBER(k)関数を使用します。

SELECT k.*, match_number(k), element_number(k)
FROM MATCH ANY SHORTEST (a:Accounts) -[e:transfers]->* (b:Accounts) ONE ROW PER VERTEX ( k )
WHERE a.acct_id = 284 AND b.acct_id = 616

前述の問合せを実行すると、次の出力が生成されます。頂点に対して戻されたelement_number(k)は奇数の値であることに注意してください。前述の問合せではANYパス・パターンを使用しているため、出力には任意のパスが1つのみ表示されます。このため、match_number(k)はパス内のすべての行で同じです。

+-----------------------------------------------------------+
| ACCT_ID | ACCT_NAME | match_number(k) | element_number(k) |
+-----------------------------------------------------------+
| 616     | Account   | 0               | 7                 |
| 744     | Account   | 0               | 5                 |
| 772     | Account   | 0               | 3                 |
| 284     | Account   | 0               | 1                 |
+-----------------------------------------------------------+

次の例に、ONE ROW PER STEPオプションを指定してMATCH_NUMBER(k)およびELEMENT_NUMBER(k)関数を使用したPGQL問合せを示します。

SELECT v1.acct_id AS src_no,k.txn_amount,v2.acct_id AS dest_no, match_number(k), element_number(k)
FROM MATCH ALL SHORTEST (a:Accounts) -[e:transfers]->+ (b:Accounts)
ONE ROW PER STEP( v1,k,v2 )
WHERE a.acct_id = 284 AND b.acct_id = 616

前述の問合せ出力は次のようになります。match_number(k)で識別されたパスが2つあり、エッジは偶数のelement_number(k)値とともに表示されています。

+---------------------------------------------------------------------+
| src_no | txn_amount | dest_no | match_number(k) | element_number(k) |
+---------------------------------------------------------------------+
| 744    | 1000.0     | 616     | 0               | 6                 |
| 772    | 1000.0     | 744     | 0               | 4                 |
| 284    | 1000.0     | 772     | 0               | 2                 |
| 744    | 1000.0     | 616     | 1               | 6                 |
| 772    | 1500.0     | 744     | 1               | 4                 |
| 284    | 1000.0     | 772     | 1               | 2                 |
+---------------------------------------------------------------------+