6.9.2.1 プロパティ・グラフ・ビューでサポートされているPGQL機能

プロパティ・グラフ・ビューでは、次のPGQL機能がサポートされています。

  • 再帰的問合せは、次の可変長パス検索の目標でサポートされています。
    • 到達可能性
    • ANY
    • ANY SHORTEST
    • TOP k SHORTEST
  • 再帰的問合せは、次の水平集計でサポートされています。
    • LISTAGG
      SELECT LISTAGG(src.first_name || ' ' || src.last_name, ',')
      FROM MATCH TOP 2 SHORTEST ( (n:Person) ((src)-[e:knows]->)* (m:Person) )
      WHERE n.id = 1234
    • SUM
      SELECT SUM(e.weight + 3)
      FROM MATCH TOP 2 SHORTEST ( (n:Person) -[e:knows]->* (m:Person) )
      WHERE n.id = 1234
    • COUNT
      SELECT COUNT(e)
      FROM MATCH TOP 2 SHORTEST ( (n:Person) -[e:knows]->* (m:Person) )
      WHERE n.id = 1234
    • AVG
      SELECT AVG(dst.age)
      FROM MATCH TOP 2 SHORTEST ( (n:Person) (-[e:knows]->(dst))* (m:Person) )
      WHERE n.id = 1234
    • MIN (プロパティ値またはCAST式の場合のみ)
      SELECT MIN(CAST(dst.age + 5 AS INTEGER))
      FROM MATCH TOP 2 SHORTEST ( (n:Person) (-[e:knows]->(dst))* (m:Person) )
      WHERE n.id = 1234
    • MAX (プロパティ値またはCAST式の場合のみ)
      SELECT MAX(dst.birthday)
      FROM MATCH TOP 2 SHORTEST ( (n:Person) (-[e:knows]->(dst))* (m:Person) )
      WHERE n.id = 1234
  • 再帰的問合せでは、次の数量詞がサポートされています。

    表6-8 PGQL SELECT問合せでサポートされる数量詞

    構文 説明
    * 0 (ゼロ)以上
    + 1以上
    ? 0 (ゼロ)または1
    {n} nに等しい
    {n,} n以上
    {n,m} nmの間(両端を含む)
    {,m} 0からmの間(両端を含む)
  • 精度とスケールによるデータ型キャストがサポートされています。
    SELECT CAST(v.id AS VARCHAR2(10)) || '→' || CAST(w.id AS VARCHAR2(10)) AS friendOf
    FROM MATCH (v) -[:friendOf]->(w)
    SELECT CAST(e.mval AS NUMBER(5,2)) AS mval
    FROM MATCH () -[e:knows]->()
    WHERE e.mval = '342.5'
  • Oracle Databaseの組込み関数とユーザー定義関数(UDF)が両方ともサポートされています。

    たとえば:

    • 表に、{"name":"John", "age": 43}などの値が含まれているJSON列があると仮定します。
      SELECT JSON_VALUE(p.attributes, '$.name') AS name
      FROM MATCH (p:Person)
      WHERE JSON_VALUE(p.attributes, '$.age') > 35
    • Oracle Text索引が表内のテキスト列に存在すると仮定します。
      SELECT n.text
      FROM MATCH (n)
      WHERE CONTAINS(n.text, 'cat', 1) > 0
    • UDFのupdated_idがグラフ・サーバー(PGX)に登録されていると仮定します。
      SELECT my.updated_id(n.ID) FROM MATCH(n) LIMIT 10
  • SELECT v.*句では、頂点またはエッジのすべてのプロパティの選択がサポートされています。vは、プロパティが選択されている変数です。次の例では、グラフのすべてのエッジ・プロパティを取得します。
    SELECT label(e), e.* FROM MATCH (n)-[e]->(m) ON bank_graph_view LIMIT 3

    実行時に、前述の問合せが、次のように変数eにバインドされているすべてのプロパティを取得します。

    +--------------------------------------------------------------+
    | label(e)  | AMOUNT | DESCRIPTION | FROM_ACCT_ID | TO_ACCT_ID |
    +--------------------------------------------------------------+
    | TRANSFERS | 1000   | transfer    | 178          | 921        |
    | TRANSFERS | 1000   | transfer    | 178          | 462        |
    | TRANSFERS | 1000   | transfer    | 179          | 688        |
    +--------------------------------------------------------------+
    

    複数の変数を使用してすべてのプロパティを選択した場合に、列名が重複しないようにPREFIXを指定できます。たとえば:

    SELECT n.* PREFIX 'n_', e.* PREFIX 'e_', m.* PREFIX 'm_' 
    FROM MATCH (n:Accounts) -[e:transfers]-> (m:Accounts) 
    ON bank_graph_view LIMIT 3

    問合せ出力は次のようになります。

    +--------------------------------------------------------------------------------------------+
    | n_ID | n_NAME  | e_AMOUNT | e_DESCRIPTION | e_FROM_ACCT_ID | e_TO_ACCT_ID | m_ID | m_NAME  |
    +--------------------------------------------------------------------------------------------+
    | 178  | Account | 1000     | transfer      | 178            | 921          | 921  | Account |
    | 178  | Account | 1000     | transfer      | 178            | 462          | 462  | Account |
    | 179  | Account | 1000     | transfer      | 179            | 688          | 688  | Account |
    +--------------------------------------------------------------------------------------------+
    

    ラベル式を使用すると、指定した頂点またはエッジ・ラベルに属するプロパティのみを選択できます。

    SELECT LABEL(n), n.* FROM MATCH (n:Accounts) ON bank_graph_view LIMIT 3

    前述の問合せ出力は次のようになります。

    +-----------------------+
    | LABEL(n) | ID | NAME  |
    +-----------------------+
    | ACCOUNTS | 1  | User1 |
    | ACCOUNTS | 2  | User2 |
    | ACCOUNTS | 3  | User3 |
    +-----------------------+
    
  • 頂点ペア間のすべてのパスを戻すALLパス検索の目標がサポートされています。ただし、無限サイクルを回避するために、次の数量詞のみがサポートされています。
    • ?
    • {n}
    • {n.m}
    • {,m}

    たとえば、次のPGQL問合せでは、アカウント284からアカウント616へのすべてのトランザクション・パスを検索します。

    SELECT LISTAGG(e.amount, ' + ') || ' = ', SUM(e.amount) AS total_amount
    FROM MATCH ALL (a:Accounts) -[e:Transfers]->{1,4}(b:Accounts)
    WHERE a.id = 284 AND b.id = 616
    ORDER BY total_amount

    実行すると、問合せによって次の結果が生成されます。

    +--------------------------------------------------+
    | LISTAGG(e.amount, ' + ') || ' = ' | TOTAL_AMOUNT |
    +--------------------------------------------------+
    | 1000 + 1000 + 1000 =              | 3000         |
    | 1000 + 1500 + 1000 =              | 3500         |
    | 1000 + 1000 + 1000 + 1000 =       | 4000         |
    +--------------------------------------------------+
    $16 ==> oracle.pg.rdbms.pgql.pgview.PgViewResultSet@4f38acf
    
  • 1列1行のみを戻すスカラー副問合せがサポートされています。

    たとえば:

    SELECT p.name AS name , (
      SELECT SUM(t.amount)      
      FROM MATCH (a) <-[t:transaction]- (:Account)  
    ) AS sum_incoming , (
      SELECT SUM(t.amount)      
      FROM MATCH (a) -[t:transaction]-> (:Account)  
    ) AS sum_outgoing , (
      SELECT COUNT(DISTINCT p2)      
      FROM MATCH (a) -[t:transaction]- (:Account) -[:owner]-> (p2:Person)    
      WHERE p2 <> p  
    ) AS num_persons_transacted_with , (
      SELECT COUNT(DISTINCT c)      
      FROM MATCH (a) -[t:transaction]- (:Account) -[:owner]-> (c:Company)  
    ) AS num_companies_transacted_with   
    FROM MATCH (p:Person) <-[:owner]- (a:Account)
    ORDER BY sum_outgoing + sum_incoming DESC
  • EXISTSおよびNOT EXISTS副問合せがサポートされています。このような問合せでは、外部問合せのバインディングが指定された場合に問合せで1つ以上の結果が生成されるかどうかに応じて、TRUEまたはFALSEになります。

    たとえば:

    SELECT fof.name, COUNT(friend) AS num_common_friends 
    FROM MATCH (p:Person) -[:knows]-> (friend:Person) -[:knows]-> (fof:Person)
    WHERE NOT EXISTS (   
      SELECT * FROM MATCH (p) -[:knows]-> (fof) 
    )
サポートされていないPGQL機能をいくつか次に示します。
  • PGQLの次のSELECT機能はサポートされていません。
    • パス式でのバインド変数の使用。

      バインド変数を使用しようとすると、次のようなエラーになります。

      opg4j> String s = "SELECT id(a) FROM MATCH ANY SHORTEST (a) -[e]->* (b) WHERE id(a) = ?";
      s ==> "SELECT id(a) FROM MATCH ANY SHORTEST (a) -[e]->* (b) WHERE id(a) = ?"
       
      opg4j> PgqlPreparedStatement ps = pgqlConn.prepareStatement(s);
      ps ==> oracle.pg.rdbms.pgql.PgqlExecution@7806db3f
       
      opg4j> ps.setString(1, "PERSON(3)");
       
      opg4j> ps.executeQuery();
      |  Exception java.lang.UnsupportedOperationException: Use of bind variables for path queries is not supported
    • in_degree関数とout_degree関数

ノート: