11.2 クイック・スタート: PGQLプロパティ・グラフの操作

このチュートリアルは、PGQLプロパティ・グラフでのグラフ・アルゴリズムの作成、問合せおよび実行を開始するのに役立ちます。

この手順では、グラフ・サーバーのインストールに付属しているサンプルの銀行グラフ・データをデータベース表にロードしたことを想定しています。詳細は、グラフ分析のサンプル・データの使用を参照してください。
次の手順は、OPG4J JavaシェルまたはOPG4PY Pythonシェルで実行することも、PGX APIを使用してJavaプログラムを通じて実行することもできる例でサポートされています。
  1. 対話型グラフ・シェルのCLIを起動します。
    cd /opt/oracle/graph
    ./bin/opg4j --no_connect
    Oracle Graph Server Shell 24.2.0
    cd /opt/oracle/graph
    ./bin/opg4py --no_connect
    Oracle Graph Server Shell 24.2.0
  2. OPG4JシェルまたはJavaプログラムを使用する場合は、JDBCデータベース接続を取得します。
    opg4j> var jdbcUrl="jdbc:oracle:thin:@<host>:<port>/<sid>"
    jdbcUrl ==> "jdbc:oracle:thin:@localhost:1521/orclpdb"
    opg4j> var conn = DriverManager.getConnection(jdbcUrl,"<username>","<password>")
    conn ==> oracle.jdbc.driver.T4CConnection@7d463c9f
    opg4j> conn.setAutoCommit(false);
    import java.sql.DriverManager;
    import java.sql.Connection;
    import java.sql.Statement;
    import oracle.pg.rdbms.pgql.PgqlConnection;
    import oracle.pg.rdbms.pgql.PgqlStatement;
    import oracle.pg.rdbms.pgql.PgqlResultSet;
    import oracle.pgx.api.*;
    import oracle.pg.rdbms.GraphServer;
    
    // Get a jdbc connection
    String jdbcUrl="jdbc:oracle:thin:@"+<host>+":"+<port>+"/"+<service>;
    conn = DriverManager.getConnection(jdbcUrl, <username>, <password>);
    conn.setAutoCommit(false);
  3. PGQL接続を作成します。
    opg4j> var pgqlConn = PgqlConnection.getConnection(conn)
    pgqlConn ==> oracle.pg.rdbms.pgql.PgqlConnection@5c5c784c
    PgqlConnection pgqlConn = PgqlConnection.getConnection(conn);
    >>> pgql_conn = opg4py.pgql.get_connection("<username>","<password>", "jdbc:oracle:thin:@<host>:<port>/<sid>")
  4. PGQL問合せを実行するためのPGQL文を作成します。
    opg4j> var pgqlStmt = pgqlConn.createStatement()
    pgqlStmt ==> oracle.pg.rdbms.pgql.PgqlExecution@29e3c28
    PgqlStatement pgqlStmt = pgqlConn.createStatement();
    >>> pgql_statement = pgql_conn.create_statement()
  5. CREATE PROPERTY GRAPH文を使用してPGQLプロパティ・グラフを作成します。
    opg4j> String pgql =
    ...> "CREATE PROPERTY GRAPH bank_graph "
    ...> + "VERTEX TABLES ( BANK_ACCOUNTS AS ACCOUNTS "
    ...> + "KEY (ID) "
    ...> + "LABEL ACCOUNTS "
    ...> + "PROPERTIES (ID, NAME) "
    ...> + ") "
    ...> + "EDGE TABLES ( BANK_TXNS AS TRANSFERS "
    ...> + "KEY (FROM_ACCT_ID, TO_ACCT_ID, AMOUNT) "
    ...> + "SOURCE KEY (FROM_ACCT_ID) REFERENCES ACCOUNTS (ID) "
    ...> + "DESTINATION KEY (TO_ACCT_ID) REFERENCES ACCOUNTS (ID) "
    ...> + "LABEL TRANSFERS "
    ...> + "PROPERTIES (FROM_ACCT_ID, TO_ACCT_ID, AMOUNT, DESCRIPTION) "
    ...> + ") OPTIONS (PG_PGQL) "
    opg4j> pgqlStmt.execute(pgql)
    String pgql = 
            "CREATE PROPERTY GRAPH " + graph + " " +
            "VERTEX TABLES ( BANK_ACCOUNTS AS ACCOUNTS " +
            "KEY (ID) " +
            "LABEL ACCOUNTS " +
            "PROPERTIES (ID, NAME)" +
            ") " +
            "EDGE TABLES ( BANK_TXNS AS TRANSFERS " +
            "KEY (FROM_ACCT_ID, TO_ACCT_ID, AMOUNT) " +
            "SOURCE KEY (FROM_ACCT_ID) REFERENCES ACCOUNTS (ID) " +
            "DESTINATION KEY (TO_ACCT_ID) REFERENCES ACCOUNTS (ID) " +
            "LABEL TRANSFERS " +
            "PROPERTIES (FROM_ACCT_ID, TO_ACCT_ID, AMOUNT, DESCRIPTION)" +
            ") OPTIONS(PG_PGQL)";
    
          pgqlStmt.execute(pgql);
    >>> pgql = """
    ...         CREATE PROPERTY GRAPH bank_graph
    ...         VERTEX TABLES (
    ...           BANK_ACCOUNTS
    ...           LABEL ACCOUNTS
    ...           PROPERTIES (ID, NAME)
    ...         )
    ...         EDGE TABLES (
    ...           BANK_TXNS
    ...             SOURCE KEY (FROM_ACCT_ID) REFERENCES BANK_ACCOUNTS (ID)
    ...             DESTINATION KEY (TO_ACCT_ID) REFERENCES BANK_ACCOUNTS (ID)
    ...             LABEL TRANSFERS
    ...             PROPERTIES (FROM_ACCT_ID, TO_ACCT_ID, AMOUNT, DESCRIPTION)
    ...         ) OPTIONS(PG_PGQL)
    ... """
    >>> pgql_statement.execute(pgql)
    False
    グラフが正常に作成されます。
  6. 次の問合せを実行して、次のように、グラフの最初の10要素を取得します。
    opg4j> String pgqlQuery =
    ...> "SELECT e.from_acct_id, e.to_acct_id, e.amount FROM "
    ...> + "MATCH (n:ACCOUNTS) -[e:TRANSFERS]-> (m:ACCOUNTS) ON BANK_GRAPH "
    ...> + "LIMIT 10"
    opg4j> var rs = pgqlStmt.executeQuery(pgqlQuery)
    rs ==> oracle.pg.rdbms.pgql.pgview.PgViewResultSet@1e368085
    opg4j> rs.print()
    +------------------------------------+
    | FROM_ACCT_ID | TO_ACCT_ID | AMOUNT |
    +------------------------------------+
    | 121          | 94         | 1000   |
    | 121          | 255        | 1000   |
    | 121          | 221        | 1000   |
    | 122          | 27         | 1000   |
    | 122          | 606        | 1000   |
    | 122          | 495        | 1000   |
    | 122          | 640        | 1000   |
    | 122          | 140        | 1000   |
    | 123          | 95         | 1000   |
    | 123          | 130        | 1000   |
    +------------------------------------+
    $16 ==> oracle.pg.rdbms.pgql.pgview.PgViewResultSet@1e368085
    String pgqlQuery = 
            "SELECT e.from_acct_id, e.to_acct_id, e.amount FROM " +
            "MATCH (n:ACCOUNTS) -[e:TRANSFERS]-> (m:ACCOUNTS) ON BANK_GRAPH " +
            "LIMIT 10";
    PgqlResultSet rs = pgqlStmt.executeQuery(pgqlQuery);
    rs.print();
    >>> pgql = """
    ... SELECT e.from_acct_id, e.to_acct_id, e.amount FROM
    ... MATCH (n:ACCOUNTS) -[e:TRANSFERS]-> (m:ACCOUNTS) on BANK_GRAPH
    ... limit 10
    ... """
    >>> pgql_statement.execute_query(pgql).print()
    +------------------------------------+
    | FROM_ACCT_ID | TO_ACCT_ID | AMOUNT |
    +------------------------------------+
    | 121          | 94         | 1000   |
    | 121          | 255        | 1000   |
    | 121          | 221        | 1000   |
    | 122          | 27         | 1000   |
    | 122          | 606        | 1000   |
    | 122          | 495        | 1000   |
    | 122          | 640        | 1000   |
    | 122          | 140        | 1000   |
    | 123          | 95         | 1000   |
    | 123          | 130        | 1000   |
    +------------------------------------+
  7. グラフをグラフ・サーバー(PGX)にロードします。これにより、様々な種類の組込みアルゴリズムをグラフで実行できるようになり、より大きなグラフの問合せパフォーマンスも改善されます。
    opg4j> var instance = GraphServer.getInstance("https://localhost:7007", "<username>", "<password>".toCharArray())
    instance ==> ServerInstance[embedded=false,baseUrl=https://localhost:7007]
    opg4j> var session = instance.createSession("mySession")
    session ==> PgxSession[ID=43653128-59cd-4e69-992c-1a2beac05857,source=mySession]
    opg4j> var graph = session.readGraphByName("BANK_GRAPH",GraphSource.PG_PGQL)
    graph ==> PgxGraph[name=BANK_GRAPH,N=1000,E=4996,created=1643308582055]
    ServerInstance instance = GraphServer.getInstance("https://localhost:7007", "<username>", "<password>".toCharArray());
    PgxSession session = instance.createSession("my-session");
    PgxGraph graph = session.readGraphByName("BANK_GRAPH",GraphSource.PG_PGQL);
    >>> instance = graph_server.get_instance("https://localhost:7007","<username>","<password>")
    >>> session = instance.create_session("my_session")
    >>> graph = session.read_graph_by_name('BANK_GRAPH', 'pg_pgql')
    >>> graph
    PgxGraph(name: BANK_GRAPH, v: 1000, e: 4996, directed: True, memory(Mb): 0)
  8. 次のように、PageRankアルゴリズムを実行します。
    opg4j> var analyst = session.createAnalyst()
    analyst ==> NamedArgumentAnalyst[session=3f0a9a71-f349-4aac-b75f-a7c4ae50851b]
    opg4j> analyst.pagerank(graph)
    $10 ==> VertexProperty[name=pagerank,type=double,graph=BANK_GRAPH]
    Analyst analyst = session.createAnalyst();
    analyst.pagerank(graph);
    >>> analyst = session.create_analyst()
    >>> analyst.pagerank(graph)
    VertexProperty(name: pagerank, type: double, graph: BANK_GRAPH)
  9. グラフを問い合せて、ページ・ランク別に上位10件のアカウントをリストします。
    opg4j> String pgql ==> "SELECT a.id, a.pagerank FROM MATCH (a) ON BANK_GRAPH ORDER BY a.pagerank DESC LIMIT 10"
    opg4j> session.queryPgql(pgql).print()
    +-----------------------------+
    | id  | pagerank              |
    +-----------------------------+
    | 387 | 0.007292323575404966  |
    | 406 | 0.0067300944623203615 |
    | 135 | 0.0067205459831892545 |
    | 934 | 0.00663484385036358   |
    | 397 | 0.005693569761570973  |
    | 559 | 0.0052584383114609844 |
    | 352 | 0.005216329599236731  |
    | 330 | 0.005093350408942336  |
    | 222 | 0.004682551613749817  |
    | 4   | 0.004569682370461633  |
    +-----------------------------+
    $18 ==> PgqlResultSetImpl[graph=BANK_GRAPH,numResults=10]
    
    String pgQuery = "SELECT a.id, a.pagerank FROM MATCH (a) ON BANK_GRAPH ORDER BY a.pagerank DESC LIMIT 10";
    session.queryPgql(pgQuery).print();
    >>> pgql = "SELECT a.id, a.pagerank FROM MATCH (a) ON BANK_GRAPH ORDER BY a.pagerank DESC LIMIT 10"
    >>> session.query_pgql(pgql).print()
    +-----------------------------+
    | id  | pagerank              |
    +-----------------------------+
    | 387 | 0.007292323575404966  |
    | 406 | 0.0067300944623203615 |
    | 135 | 0.0067205459831892545 |
    | 934 | 0.00663484385036358   |
    | 397 | 0.005693569761570973  |
    | 559 | 0.0052584383114609844 |
    | 352 | 0.005216329599236731  |
    | 330 | 0.005093350408942336  |
    | 222 | 0.004682551613749817  |
    | 4   | 0.004569682370461633  |
    +-----------------------------+