18.3 グラフ・サーバー(PGX)でサポートされているPGQL機能および制限事項
グラフ・サーバー(PGX)でサポート対象のPGQL機能、およびサポート対象外のPGQL機能について学習します。
表18-2 グラフ・サーバー(PGX)でサポートされているPGQL機能および制限事項
機能 | グラフ・サーバー上のPGQL (PGX) |
---|---|
CREATE PROPERTY GRAPH |
サポート対象
制限事項:
|
DROP PROPERTY GRAPH |
サポート対象外 |
固定長パターン一致 | サポート対象 |
可変長パターン一致の目標 | サポート対象:
|
可変長パターン一致の数量詞 | サポート対象:
制限事項:
|
可変長パスのネスト解除 | サポート対象:
制限事項:
|
GROUP BY |
サポート対象 |
HAVING |
サポート対象 |
集計 | サポート対象:
サポート対象外
|
DISTINCT
|
サポート対象 |
SELECT v.* |
サポート対象 |
ORDER BY (+ASC/DESC)、LIMIT、OFFSET |
サポート対象 |
データ型 | サポート対象:
|
JSON | 組込みのJSONサポートはありません。ただし、JSON値はSTRING として格納でき、JavaまたはJavaScriptで記述されたユーザー定義関数(UDF)を使用して操作または問合せできます。
|
演算子 | サポート対象:
|
関数および述語 | サポート対象:
|
ユーザー定義関数 | サポート対象:
|
副問合せ:
|
サポート対象
制限事項
|
GRAPH_TABLE 演算子
|
サポート対象
制限事項
|
INSERT/UPDATE/DELETE |
サポート対象 |
INTERVAL リテラルおよび操作
|
サポートされているリテラル:
サポートされている操作:
|
また、次では、特定のサポートされているPGQL機能とサポートされていないPGQL機能についても説明します:
- すべてのプロパティの選択のサポート
- 可変長パス問合せのネスト解除
- PGQL問合せでのINTERVALリテラルの使用
- PGQLでのパス・モードの使用
- PGQL Lateral副問合せのサポート
- PGQL GRAPH_TABLE演算子のサポート
- 数量詞の制限
- 定量化されたパターンでのWHERE句およびCOST句の制限事項
親トピック: グラフ・サーバー(PGX)に対するPGQL問合せの実行
18.3.1 すべてのプロパティの選択のサポート
SELECT v.*
を使用して、変数v
にバインドする頂点またはエッジのすべてのプロパティを選択できます。たとえば:
SELECT label(n), n.* FROM MATCH (n) ORDER BY "number", "name"
実行時に、問合せ出力は次のようになります。
+-----------------------------+
| label(n) | number | name |
+-----------------------------+
| Account | 1001 | <null> |
| Account | 2090 | <null> |
| Account | 8021 | <null> |
| Account | 10039 | <null> |
| Person | <null> | Camille |
| Person | <null> | Liam |
| Person | <null> | Nikita |
| Company | <null> | Oracle |
+-----------------------------+
ラベル式を使用して、指定した頂点ラベルまたはエッジ・ラベルに属するプロパティを選択できます。たとえば:
SELECT label(n), n.* FROM MATCH (n:Person) ORDER BY "name"
前述の問合せは、指定されたPerson
ラベルのすべてのプロパティを取得します。
+--------------------+
| label(n) | name |
+--------------------+
| Person | Camille |
| Person | Liam |
| Person | Nikita |
+--------------------+
複数の変数を使用してすべてのプロパティを選択した場合、列名が重複しないようにPREFIX
を指定することもできます。たとえば:
SELECT n.* PREFIX 'n_', e.* PREFIX 'e_', m.* PREFIX 'm_'
FROM MATCH (n:Account) -[e:transaction]-> (m:Account)
ORDER BY "e_amount"
問合せの出力は次のようになります。
+--------------------------------+
| n_number | e_amount | m_number |
+--------------------------------+
| 10039 | 1000.0 | 8021 |
| 8021 | 1500.3 | 1001 |
| 8021 | 3000.7 | 1001 |
| 2090 | 9900.0 | 10039 |
| 1001 | 9999.5 | 2090 |
+--------------------------------+
18.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
を使用してエッジを視覚化することもできます。
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 VERTEX
、ONE 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 |
+---------------------------------------------------------------------+
18.3.3 PGQL問合せでのINTERVALリテラルの使用
PGQL問合せでINTERVAL
リテラルを使用すると、PGQL Temporalデータ型に対する間隔の加算または減算をそれぞれ実行できます。
INTERVAL
型は期間で、キーワード"INTERVAL
"とそれに続く数値および時間単位で構成されます。たとえば、INTERVAL '1' DAY
となります。
次の表に、INTERVAL
値でサポートされる有効な時間単位を示します。
表18-3 INTERVAL
値のフィールドの有効な値
キーワード | サポートされる有効な値 |
---|---|
YEAR |
<間隔先行フィールド精度>以外は制約なし |
MONTH |
月(年単位) (0-11) |
DAY |
<間隔先行フィールド精度>以外は制約なし |
HOUR |
時間(日単位) (0-23) |
MINUTE |
分(時間単位) (0-59) |
SECOND |
秒(分単位) (0-59.999...) |
次のINTERVAL
操作がTemporalデータ型でサポートされています。
TEMPORAL TYPE + INTERVAL
INTERVAL + TEMPORAL TYPE
TEMPORAL TYPE - INTERVAL
たとえば、次のPGQL問合せでは、n.birthdate + INTERVAL '20' YEAR > TIMESTAMP '2000-01-01 00:00:00'
である個人を取得します。
opg4j> graph.queryPgql("SELECT n.name, n.birthdate FROM MATCH (n:Person) WHERE n.birthdate + INTERVAL '20' YEAR > TIMESTAMP '2000-01-01 00:00:00'").print()
graph.queryPgql("SELECT n.name, n.birthdate FROM MATCH (n:Person) WHERE n.birthdate + INTERVAL '20' YEAR > TIMESTAMP '2000-01-01 00:00:00'").print();
graph.query_pgql("SELECT n.name, n.birthdate FROM MATCH (n:Person) WHERE n.birthdate + INTERVAL '20' YEAR > TIMESTAMP '2000-01-01 00:00:00'").print()
実行時に、問合せ出力は次のようになります。
+--------------------------+
| name | birthdate |
+--------------------------+
| Mary | 1982-09-25T00:00 |
| Alice | 1987-02-01T00:00 |
+--------------------------+
18.3.4 PGQLでのパス・モードの使用
次のパス・モードは、ANY
、ALL
、ANY SHORTEST
、SHORTEST k
、およびALL SHORTEST
と組み合せて使用できます。
WALK
(デフォルト・パス・モード):ウォークは、一連の頂点とエッジを介してグラフをトラバースします。ウォークでアクセスした頂点とエッジを繰り返すことができます。したがって、このデフォルトのパス・モードではパスのフィルタリングは行われません。TRAIL
:トレイルはエッジを繰り返すことなくグラフをトラバースしています。したがって、エッジを繰り返すパス・バインディングは返されません。
前述の出力では、両方のパスに頂点8021と1001が2回含まれていますが、エッジが繰り返されないかぎり、まだトレイルは有効です。SELECT CAST(a.number AS STRING) || ' -> ' || LISTAGG(x.number, ' -> ') AS accounts_along_path FROM MATCH ALL TRAIL PATHS (a IS account) (-[IS transaction]-> (x)){2,} (b IS Account) WHERE a.number = 8021 AND b.number = 1001 +-----------------------------------------------+ | accounts_along_path | +-----------------------------------------------+ | 8021 -> 1001 -> 2090 -> 10039 -> 8021 -> 1001 | | 8021 -> 1001 -> 2090 -> 10039 -> 8021 -> 1001 | +-----------------------------------------------+
ACYCLIC
:グラフ・トラバースの開始頂点と終了頂点が異なる場合、これはパスにサイクルがないことを意味します。この場合、頂点が繰り返されるパス・バインディングは返されません。
前述の問合せで、10の最短パスがリクエストされました。ただし、他のすべてのパスが循環するため、2つのみが返されます。SELECT CAST(a.number AS STRING) || ' -> ' || LISTAGG(x.number, ' -> ') AS accounts_along_path FROM MATCH SHORTEST 10 ACYCLIC PATHS (a IS account) (-[IS transaction]-> (x))+ (b) WHERE a.number = 10039 AND b.number = 1001 +-----------------------+ | accounts_along_path | +-----------------------+ | 10039 -> 8021 -> 1001 | | 10039 -> 8021 -> 1001 | +-----------------------+
SIMPLE
: 単純なウォークは、頂点を繰り返さずにグラフをトラバースします。したがって、頂点を繰り返すパス・バインディングは返されません。唯一の例外は、繰り返される頂点がパスの最初の頂点と最後の頂点であることです。
前述の問合せは循環パスを返します。このパスは、同じ頂点で開始および終了し、パスに他のサイクルがないため、有効かつ単純なパスです。SELECT CAST(a.number AS STRING) || ' -> ' || LISTAGG(x.number, ' -> ') AS accounts_along_path FROM MATCH ANY SIMPLE PATH (a IS account) (-[IS transaction]-> (x))+ (a) WHERE a.number = 10039 +----------------------------------------+ | accounts_along_path | +----------------------------------------+ | 10039 -> 8021 -> 1001 -> 2090 -> 10039 | +----------------------------------------+
パス・モードは、構文的にはANY
、ALL
、ANY SHORTEST
、SHORTEST k
、ALL SHORTEST
、CHEAPEST
およびCHEAPEST k
の後に配置されます。パス・モードの後には、PATH
またはPATHS
キーワードが続くこともあります。
すべての無限量数量詞に対してTRAIL
、ACYCLIC
またはSIMPLE
の一致パス・モードを使用すると、グラフ・パターン一致の結果セットが有限であることが保証されます。
18.3.5 PGQL Lateral副問合せのサポート
LATERAL
副問合せを使用して、ある問合せの出力行を別の問合せに渡すことができます。サポートされているのは単一のLATERAL
副問合せのみです。
たとえば、別のORDER BY
句またはGROUP BY
句の上にORDER BY
句またはGROUP BY
句を使用できます。
/* Find the top-5 largest transactions and return the account number
that received the highest number of such large transactions */
SELECT recipient, COUNT(*) AS num_large_transactions
FROM LATERAL ( SELECT m.number AS recipient
FROM MATCH (n:account) -[e:transaction]-> (m:account)
ORDER BY e.amount DESC
LIMIT 5 )
GROUP BY recipient
ORDER BY num_large_transactions DESC
LIMIT 1
また、FROM
句のLATERAL
副問合せの後に1つ以上のMATCH
句を指定できます。たとえば:
SELECT path_num, elem_num, owner.name
FROM LATERAL ( SELECT v, MATCHNUM(v) AS path_num, ELEMENT_NUMBER(v) AS elem_num
FROM MATCH SHORTEST 2 PATHS (a1:account) -[e:transaction]->* (a2:account)
ONE ROW PER VERTEX ( v )
WHERE a1.number = 10039 AND a2.number = 2090 )
, MATCH (v) -[:owner]-> (owner:Person|Company)
ORDER BY path_num, elem_num
FROM
句にLATERAL
副問合せが含まれている場合、LATERAL
副問合せはFROM句の最初の表式である必要があることに注意することが重要です。FROM句には追加のMATCH句を含めることができますが、追加のLATERAL副問合せを含めることはできません。
18.3.6 PGQL GRAPH_TABLE演算子のサポート
PGQLのGRAPH_TABLE
演算子によって、グラフ・サーバー(PGX)にロードされるグラフとデータベース上のグラフの間の相互運用性が向上します。
- グラフ・パターン
MATCH
問合せのラベル述語では、IS
キーワードを使用する必要があります。 - 出力行数を制限するには、
LIMIT x
句のかわりにFETCH [FIRST/NEXT] x [ROW/ROWS]
句を使用します。 - エッジの方向を確認するには、
[NOT] is_source_of(e, v)
/[NOT] is_destination_of(e, v)
のかわりにv IS [NOT] SOURCE [OF] e
/v IS [NOT] DESTINATION [OF] e
を標準フォームとして使用します。 - 頂点またはエッジに指定したラベルがあるかどうかを確認するには、
has_label(x, <label_string>)
の代替としてx IS [NOT] LABELED <label_string>
述語を使用します。 k
の最短パスと一致させるには、MATCH (n) –[e]->* (m) KEEP SHORTEST k
をMATCH TOP k SHORTEST (n) –[e]->* (m)
の標準形式として使用します。- 固定長パス・パターンの前には
ALL
キーワード(オプション)があります。MATCH ALL (n) –[e]->{1,4} (m)
の代替としてのMATCH (n) –[e]->{1,4} (m)
。 MATCH <path pattern prefix> <path pattern> <WHERE clause>
の代替としてのMATCH <path pattern> KEEP <path pattern prefix> <WHERE clause>
次に、GRAPH_TABLE
演算子を使用した問合せの例をいくつか示します:
例18-2 TRAIL
パス・モードとALL
を使用した集計問合せ
SELECT *
FROM GRAPH_TABLE ( financial_transactions
MATCH ALL TRAIL (a IS account) -[e IS transaction]->* (b IS account)
/* optional ONE ROW PER VERTEX/STEP clause here */
WHERE a.number = 8021 AND b.number = 1001
COLUMNS ( LISTAGG(e.amount, ', ') AS amounts )
)ORDER BY amounts
この問合せの出力は次のようになります。
+----------------------------------------+
| amounts |
+----------------------------------------+
| 1500.3 |
| 1500.3, 9999.5, 9900.0, 1000.0, 3000.7 |
| 3000.7 |
| 3000.7, 9999.5, 9900.0, 1000.0, 1500.3 |
+----------------------------------------+
例18-3 KEEP
句を使用した集計問合せ
SELECT *
FROM GRAPH_TABLE ( financial_transactions
MATCH (a IS Account) -[e IS transaction]->+ (a)
KEEP SIMPLE PATHS
WHERE a.number = 10039
COLUMNS ( LISTAGG(e.amount, ', ') AS amounts_along_path,
SUM(e.amount) AS total_amount )
)
ORDER BY total_amount DESC
この問合せの出力は次のようになります。
+-----------------------------------------------+
| amounts_along_path | total_amount |
+-----------------------------------------------+
| 1000.0, 3000.7, 9999.5, 9900.0 | 23900.2 |
| 1000.0, 1500.3, 9999.5, 9900.0 | 22399.8 |
+-----------------------------------------------+
18.3.7 数量詞の制限
到達可能性パターンと最短パス・パターンでは、*
、+
、{1,4}
などのすべての数量詞がサポートされていますが、最小コスト・パス・パターンでサポートされている数量詞は*
(ゼロ以上)のみです。
18.3.8 定量化されたパターンでのWHERE句およびCOST句の制限事項
到達可能性パターンや最短パス・パターンおよび最小コスト・パス・パターンなどの定量化されたパターンのWHERE
句およびCOST
句は、単一の変数の参照のみに制限されます。
次に、WHERE
句またはCOST
句が、zero
またはone
のかわりに2つの変数e
およびx
を参照しているためにサポートされていない問合せの例を示します。
... PATH p AS (n) –[e]-> (m) WHERE e.prop > m.prop ...
... SHORTEST ( (n) (-[e]-> (x) WHERE e.prop + x.prop > 10)* (m) ) ...
... CHEAPEST ( (n) (-[e]-> (x) COST e.prop + x.prop )* (m) ) ...
次の問合せがサポートされているのは、副問合せは外部スコープから単一の変数a
のみを参照し、変数c
は副問合せで新たに導入されたためにカウントされないためです。
... PATH p AS (a) -> (b)
WHERE EXISTS ( SELECT * FROM MATCH (a) -> (c) ) ...