7.8 コンポジット・キーを使用したSQLプロパティ・グラフのロード

完全なSQLプロパティ・グラフまたはコンポジット・キーを持つサブグラフを、サーバー生成IDを使用してグラフ・サーバー(PGX)メモリーにロードできます。

コンポジット頂点(FIRST_NAMELAST_NAME)およびエッジ(USER1_FIRST_NAMEUSER1_LAST_NAMEUSER2_FIRST_NAMEUSER2_LAST_NAME)キーで定義される次のSQLプロパティ・グラフについて考えてみます:
CREATE PROPERTY GRAPH SOCIAL_NETWORK
    VERTEX TABLES (
      USERS
         KEY (FIRST_NAME, LAST_NAME)
         PROPERTIES (FULL_NAME, USERNAME)
    ) 
    EDGE TABLES (
      FRIENDS_WITH 
        KEY (USER1_FIRST_NAME, USER1_LAST_NAME, USER2_FIRST_NAME, USER2_LAST_NAME) 
        SOURCE KEY (USER1_FIRST_NAME, USER1_LAST_NAME) REFERENCES USERS (FIRST_NAME, LAST_NAME)
        DESTINATION KEY (USER2_FIRST_NAME, USER2_LAST_NAME) REFERENCES USERS (FIRST_NAME, LAST_NAME)
        NO PROPERTIES
    ) OPTIONS (ENFORCED MODE);
  1. 次のように、readGraphByName APIを使用してグラフ・サーバー(PGX)メモリーに完全なグラフをロードします:
    opg4j> var graph = session.readGraphByName("SOCIAL_NETWORK", GraphSource.PG_SQL)
    graph ==> PgxGraph[name=SOCIAL_NETWORK,N=3,E=3,created=1742566083153]
    PgxGraph graph = session.readGraphByName("SOCIAL_NETWORK", GraphSource.PG_SQL);
    >>> graph = session.read_graph_by_name("SOCIAL_NETWORK", "pg_sql")
    >>> graph
    PgxGraph(name: SOCIAL_NETWORK, v: 3, e: 3, directed: True, memory(Mb): 0)

    また、コンポジット・キーを使用してグラフを作成する場合は、次の点に注意することが重要です:

    • グラフの作成時にENFORCED MODEを有効にすることをお薦めします。これは、指定したコンポジット・キーの一意性を確保し、同じ頂点またはエッジが重複したキーで複数回ロードされないようにするためです。
    • これらのIDは自動的に生成されるため、グラフ・エンティティとデータベース要素の間にはキーのマッピングがありません。したがって、これらのグラフは同期できません。
    • SQLプロパティ・グラフのキー列に関連するメタデータを格納するデータ・ディクショナリ・ビューでは、次のようにコンポジット・キーが更新されます:
      SQL> SELECT ELEMENT_NAME, COLUMN_NAME from ALL_PG_KEYS WHERE GRAPH_NAME = 'SOCIAL_NETWORK';
      
      ELEMENT_NAME         COLUMN_NAME
      -------------------- --------------------
      USERS                FIRST_NAME
      USERS                LAST_NAME
      FRIENDS_WITH         USER1_FIRST_NAME
      FRIENDS_WITH         USER1_LAST_NAME
      FRIENDS_WITH         USER2_FIRST_NAME
      FRIENDS_WITH         USER2_LAST_NAME
      
      6 rows selected.
  2. オプションで、グラフ・サーバー(PGX)のグラフを問い合せて、自動生成された頂点キーおよびエッジ・キーを表示します。
    opg4j> var pgql =
    ...>   "SELECT * "+
    ...>   "FROM GRAPH_TABLE ( social_network "+
    ...>   "MATCH (a IS users) -[e IS friends_with]-> (b IS users) "+
    ...>   "COLUMNS (vertex_id(a), a.full_name, edge_id(e), b.full_name AS friend) "+
    ...> ")"
    pgql ==> "SELECT * FROM GRAPH_TABLE ( social_network MATCH (a IS users) -[e IS friends_with]-> (b IS users) COLUMNS (vertex_id(a), a.full_name, edge_id(e), b.full_name AS friend) )"
    opg4j> g.queryPgql(pgql).print()
    +------------------------------------------------------------+
    | vertex_id(a) | full_name   | edge_id(e)      | friend      |
    +------------------------------------------------------------+
    | USERS(0)     | Steven King | FRIENDS_WITH(0) | Tom Rogers  |
    | USERS(1)     | Tom Rogers  | FRIENDS_WITH(1) | Peter Hall  |
    | USERS(2)     | Peter Hall  | FRIENDS_WITH(2) | Steven King |
    +------------------------------------------------------------+
    $27 ==> PgqlResultSetImpl[graph=SOCIAL_NETWORK,numResults=3]
    String pgql = "SELECT * "+
      "FROM GRAPH_TABLE ( social_network "+
      "MATCH (a IS users) -[e IS friends_with]-> (b IS users) "+
      "COLUMNS (vertex_id(a), a.full_name, edge_id(e), b.full_name) "+
    ")";
    PgqlResultSet rs = g.queryPgql(pgql);
    rs.print();
    >>> pgql = """
    ... SELECT *
    ... FROM GRAPH_TABLE ( social_network
    ... MATCH (a IS users) -[e IS friends_with]-> (b IS users)
    ... COLUMNS (vertex_id(a), a.full_name, edge_id(e), b.full_name as name_of_friend)
    ... )
    ... """
    >>> graph.query_pgql(pgql).print()
    +---------------------------------------------------------------+
    | vertex_id(a) | full_name   | edge_id(e)      | name_of_friend |
    +---------------------------------------------------------------+
    | USERS(0)     | Steven King | FRIENDS_WITH(0) | Tom Rogers     |
    | USERS(1)     | Tom Rogers  | FRIENDS_WITH(1) | Peter Hall     |
    | USERS(2)     | Peter Hall  | FRIENDS_WITH(2) | Steven King    |
    +---------------------------------------------------------------+
  3. オプションで、コンポジット・キーを使用するSOCIAL_NETWORKグラフのサブグラフのみをロードおよび問合せします。
    opg4j> var subGraph = session.readSubgraph().
    ...>     fromPgSql("SOCIAL_NETWORK").
    ...>     queryPgql("MATCH (v1 IS users)-[e IS friends_with]->(v2 IS users) WHERE v1.full_name = 'Peter Hall'").
    ...>     load()
    graph ==> PgxGraph[name=SOCIAL_NETWORK_2,N=2,E=1,created=1743066245310]
    
    opg4j> subGraph.queryPgql("SELECT v1.full_name as name, v2.full_name as name_of_friend from MATCH (v1 IS users)-[e IS friends_with]->(v2 IS users)").print()
    +-----------------------------+
    | name       | name_of_friend |
    +-----------------------------+
    | Peter Hall | Steven King    |
    +-----------------------------+
    $11 ==> PgqlResultSetImpl[graph=SOCIAL_NETWORK_3,numResults=1]
    PgxGraph subGraph = session.readSubgraph()
      .fromPgSql("SOCIAL_NETWORK")
      .queryPgql("MATCH (v1 IS users)-[e IS friends_with]->(v2 IS users) WHERE v1.full_name = 'Peter Hall'")
      .load();
    
    PgqlResultSet rs = subGraph.queryPgql("SELECT v1.full_name as name, v2.full_name as name_of_friend from MATCH (v1 IS users)-[e IS friends_with]->(v2 IS users)");
    rs.print();
    >>> sub_graph = session.read_subgraph_from_pg_sql("SOCIAL_NETWORK",
    ...     "MATCH (v1 IS users)-[e IS friends_with]->(v2 IS users) WHERE v1.full_name = 'Peter Hall'",
    ...     graph_name = "nw_sub_graph")
    
    >>> sub_graph.query_pgql("SELECT v1.full_name as name, v2.full_name as name_of_friend from MATCH (v1 IS users)-[e IS friends_with]->(v2 IS users)").print()
    +-----------------------------+
    | name       | name_of_friend |
    +-----------------------------+
    | Peter Hall | Steven King    |
    +-----------------------------+
    また、コンポジット・キーを使用するグラフからサブグラフをロードする場合、次の制限に注意してください:
    • 自動生成されたキーIDに依存する条件に基づくサブグラフのロードはサポートされていません。たとえば、MATCH (V) WHERE ID(V) = 'Person(0)' です
    • 自動生成されたIDを持つサブグラフは展開できません。