2.1.1.1 データベースでのグラフの作成および問合せ

このセクションでは、Oracle Graphクライアントを使用してリレーショナル表からグラフを作成し、データベースのプロパティ・グラフ・スキーマに格納します。

シェルの起動

Oracle Graphクライアントがインストールされているシステムで、次のようにしてシェルを起動します。
cd <client-install-dir>
./bin/opg4j --noconnect 

--noconnectオプションは、インメモリー・グラフ・サーバー(PGX)に接続していないことを示します。この例では、データベースにのみ接続します。

シェルを起動する前に、JAVA_HOMEをJava 11に設定する必要があることに注意してください。次に例を示します。
export JAVA_HOME=/usr/lib/jvm/java-11-oracle

シェルの詳細は、対話型グラフ・シェルを参照してください。

JDBCデータベース接続を開く

シェル・プロンプト内で、標準のJDBC Java APIを使用して、データベース接続オブジェクトを取得します。次に例を示します。
opg4j> var jdbcUrl = "<jdbc-url>" // for example: jdbc:oracle:thin:@myhost:1521/myservice
opg4j> var user = "<db-user>" // for example: hr
opg4j> var pass = "<db-pass>"
opg4j> var conn = DriverManager.getConnection(jdbcUrl, user, pass)
conn ==> oracle.jdbc.driver.T4CConnection@57e6cb01

Autonomous Databaseへの接続も同様に機能します。ローカル・ウォレットを指すJDBC URLを指定します。例は、Autonomous DatabaseでのOracle Graphの使用を参照してください。

PGQL接続の作成

JDBC接続をPGQL接続オブジェクトに変換します。次に例を示します。
opg4j> conn.setAutoCommit(false)
opg4j> var pgql = PgqlConnection.getConnection(conn)
pgql ==> oracle.pg.rdbms.pgql.PgqlConnection@6fb3d3bb

グラフ作成文の作成および実行

テキスト・エディタを使用して、HRサンプル・データをグラフに変換する方法を記述するCREATE PROPERTY GRAPH文を作成します。このファイルをcreate.pgqlとして任意の場所に保存します。次に例を示します。
CREATE PROPERTY GRAPH hr
  VERTEX TABLES (
    employees LABEL employee
      PROPERTIES ARE ALL COLUMNS EXCEPT ( job_id, manager_id, department_id ),
    departments LABEL department
      PROPERTIES ( department_id, department_name ),
    jobs LABEL job
      PROPERTIES ARE ALL COLUMNS,
    job_history
      PROPERTIES ( start_date, end_date ),
    locations LABEL location
      PROPERTIES ARE ALL COLUMNS EXCEPT ( country_id ),
    countries LABEL country
      PROPERTIES ARE ALL COLUMNS EXCEPT ( region_id ),
    regions LABEL region
  )
  EDGE TABLES (
    employees AS works_for
      SOURCE employees
      DESTINATION KEY ( manager_id ) REFERENCES employees
      NO PROPERTIES,
    employees AS works_at
      SOURCE employees
      DESTINATION departments
      NO PROPERTIES,
    employees AS works_as
      SOURCE employees
      DESTINATION jobs
      NO PROPERTIES,
    departments AS managed_by
      SOURCE departments
      DESTINATION employees
      NO PROPERTIES,
    job_history AS for_employee
      SOURCE job_history
      DESTINATION employees
      LABEL for
      NO PROPERTIES,
    job_history AS for_department
      SOURCE job_history
      DESTINATION departments
      LABEL for
      NO PROPERTIES,
    job_history AS for_job
      SOURCE job_history
      DESTINATION jobs
      LABEL for
      NO PROPERTIES,
    departments AS department_located_in
      SOURCE departments
      DESTINATION locations
      LABEL located_in
      NO PROPERTIES,
    locations AS location_located_in
      SOURCE locations
      DESTINATION countries
      LABEL located_in
      NO PROPERTIES,
    countries AS country_located_in
      SOURCE countries
      DESTINATION regions
      LABEL located_in
      NO PROPERTIES
  )
次に、グラフ・シェルに戻り、CREATE PROPERTY GRAPH文をPGQL接続に送信して実行します。<path>を、create.pgqlファイルを含むディレクトリのパスに置き換えます。
opg4j> pgql.prepareStatement(Files.readString(Paths.get("<path>/create.pgql"))).execute()
$16 ==> false

いくつかのPGQL問合せの実行

これで、hrというグラフが作成されたので、PGQLを使用して、データベース上で直接そのグラフに対していくつかの問合せを実行できます。次に例を示します。
// define a little helper function that executes the query, prints the results and properly closes the statement
opg4j> Consumer<String> query = q -> { try(var s = pgql.prepareStatement(q)) { s.execute(); s.getResultSet().print(); } catch(Exception e) { throw new RuntimeException(e); } }
query ==> $Lambda$605/0x0000000100ae6440@6c9e7af2
 
// print the number of vertices in the graph
opg4j> query.accept("select count(v) from hr match (v)")
+----------+
| count(v) |
+----------+
| 215      |
+----------+
 
// print the number of edges in the graph
opg4j> query.accept("select count(e) from hr match ()-[e]->()")
+----------+
| count(e) |
+----------+
| 433      |
+----------+
 
// find the highest earning managers
opg4j> query.accept("select distinct m.FIRST_NAME, m.LAST_NAME, m.SALARY from hr match (v:EMPLOYEE)-[:WORKS_FOR]->(m:EMPLOYEE) order by m.SALARY desc")
+---------------------------------------+
| m.FIRST_NAME | m.LAST_NAME | m.SALARY |
+---------------------------------------+
| Steven       | King        | 24000.0  |
| Lex          | De Haan     | 17000.0  |
| Neena        | Kochhar     | 17000.0  |
| John         | Russell     | 14000.0  |
| Karen        | Partners    | 13500.0  |
| Michael      | Hartstein   | 13000.0  |
| Alberto      | Errazuriz   | 12000.0  |
| Shelley      | Higgins     | 12000.0  |
| Nancy        | Greenberg   | 12000.0  |
| Den          | Raphaely    | 11000.0  |
| Gerald       | Cambrault   | 11000.0  |
| Eleni        | Zlotkey     | 10500.0  |
| Alexander    | Hunold      | 9000.0   |
| Adam         | Fripp       | 8200.0   |
| Matthew      | Weiss       | 8000.0   |
| Payam        | Kaufling    | 7900.0   |
| Shanta       | Vollman     | 6500.0   |
| Kevin        | Mourgos     | 5800.0   |
+---------------------------------------+
 
// find the average salary of accountants in the Americas
opg4j> query.accept("select avg(e.SALARY) from hr match (e:EMPLOYEE) -[h:WORKS_AT]-> (d:DEPARTMENT) -[:LOCATED_IN]-> (:LOCATION) -[:LOCATED_IN]-> (:COUNTRY) -[:LOCATED_IN]-> (r:REGION) where r.REGION_NAME = 'Americas' and d.DEPARTMENT_NAME = 'Accounting'")
+---------------+
| avg(e.SALARY) |
+---------------+
| 14500.0       |
+---------------+