Oracle Property Graph serverのセットアップとその活用方法

この記事は、RexZhengさんが執筆した記事の日本語改定版です。
注(記事内容はアップデート作業中のため、バージョンなどは適宜修正中です。基本的な操作に大幅な変更はありません)

本記事は[こちら](https://qiita.com/RexZheng/items/4b75efd1149d67cf93bf#get-auth-token)から。

この記事では、Oracle Cloud Infrastructure Database System の VM インスタンスに Oracle Property Graph Server and Client をインストールし、環境構築後、VM インスタンス上の Graph Server とデータベースそれぞれにクライアント側から正しく接続するための設定方法も紹介していきます。
今回説明している構築方法はオンプレミスの環境にGraph Server and Clientを構築する際にも参考になります。
クラウドのみでセットアップする場合には、事前に準備されたイメージを用いる手軽な方法があるため、こちらの記事もご参照ください。


上記のセットアップ手順だけではなく、2つのサンプルも用意していますので、グラフテクノロジーを体感していきましょう！

#今回の環境
本記事での環境をまとめたリストはこちら

- Oracle Property Graph Server 21.2
- Oracle Property Graph Client 21.2
- Oracle Database Software Edition: Enterprise Edition High Performance
- DB System Version: 19.9.0.0.0
- Oracle Linux 7.8 x64
- Oracle JDK 11
- Browser: Firefox

#PL/SQL Packages
事前に、Oracle Graph Server and Client の最新の PL/SQL パッケージを自分でインストールする必要があります。Oracle Database 12.2以降であれば、Oracle Graph Server and Client は Oracle Database のバージョン 12.2 以降で動作可能です。
Oracle Graph Client for PL/SQLのダウンロードはこちら↓
https://www.oracle.com/database/technologies/spatialandgraph/property-graph-features/graph-server-and-client/graph-server-and-client-downloads.html


Download `Oracle Graph Client for PL/SQL`をダウンロード後、任意のディレクトリ内で解凍して下さい。
解凍したら、そのディレクトリ内でOracle Databaseにログインして、下記のクエリを実行して設定をします。

注: ダウンロードしたファイルには2つのディレクトリがあると思います。DBA権限を持つデータベースユーザとして、REAME.mdファイル内の指示に従って下さい。自分のデータベースのバージョンと指示が合っているか確認をしてください。これは、グラフ機能が入ったPDBを使用する際に、毎回必要になります。今回はDBCSインスタンスは19cなので、`19c_and_above`のスクリプトを流していきます。

```sql
-- 解凍済みのディレクトリ内でsqlplusにSYSDBAで接続
SQL> alter session set container=<YOUR_PDB_NAME>;
SQL> @opgremov.sql
SQL> @catopg.sql
```

#Oracle Property Graph Server and Clientのインストール
Oracle Graph Server and Client 21.2.の最新バージョンをインストールします。
下記のページからインストールパッケージをダウンロード可能です。
[Oracle Graph Server and Client Downloads](https://www.oracle.com/database/technologies/spatialandgraph/property-graph-features/graph-server-and-client/graph-server-and-client-downloads.html)

#Oracle JDK 11のインストール
Oracle Graph Server and Clientは20.4から同じJDKバージョンであるJDK 11を使うようになりました。
JDK 11をまずはダウンロードします。

Java SE Development Kit 11 Downloads
https://www.oracle.com/java/technologies/javase-jdk11-downloads.html

```sh
sudo rpm -i jdk-11.0.9_linux-x64_bin.rpm
java --version
opc@db19h graph]$
```

#Oracle Property Graph Server 21.2.
##インストール
下記のコマンドでOracle Property graph Serverをインストールを始めます。

```sh
sudo rpm -i oracle-graph-20.4.0.x86_64.rpm
```
このコマンドは実行してもレスポンスは返ってきません。
下記のコマンドよりOracle Property Graph Serverをスタートさせることができます。

```sh
sudo systemctl start pgx
systemctl status pgx
sudo systemctl stop pgx
```

##Oracle Databaseの設定
`oracle`ユーザに変更し、`sys`としてデータベースに接続します。

```sh
sudo su - oracle
sqlplus / as sysdba
```

PDBの`pdb1`に `demograph`というユーザを作成します。
下記のようにロールと表領域を与えていきます。
全ての表は、スキーマ`demograph`に作成され、ロードされます。

```sql
CREATE USER demograph IDENTIFIED BY <PASSWORD>;
GRANT CONNECT, resource TO demograph;
GRANT CREATE VIEW TO demograph;

CREATE ROLE graph_developer;
CREATE ROLE graph_administrator;

GRANT graph_developer TO demograph;
GRANT graph_administrator to demograph;

ALTER USER demograph QUOTA 10G ON USERS;

GRANT UNLIMITED TABLESPACE TO demograph;
```

##Oracle Property Graph Serverの設定
`graph`というシステムユーザを追加します

```sh
sudo useradd graph
sudo usermod -a -G oraclegraph graph
sudo passwd graph
```

`pgx.conf`という設定ファイルの中にJDB connection stringを追加します

```sh
sudo vim /etc/oracle/graph/pgx.conf
jdbc:oracle:thin:@//db19h.sub11160238550.graphvcntokyo.oraclevcn.com:1521/pdb1.sub11160238550.graphvcntokyo.oraclevcn.com

```

connection stringはDBCSウェブコンソールから手に入ります。
もしくは、`lsnrctl status`コマンドからサービス名を確認しましょう。

ユーザ`demograph`は`pdb1`内に作成されたので,今回の例でのconnection stringは`pdb1`になります。


`server.conf`(設定ファイル) を編集

`enable_tls`を`false`に設定。

```sh
sudo vim /etc/oracle/graph/server.conf
```

##PGX serviceを再起動

```sh
sudo systemctl restart pgx
sudo systemctl status pgx
```

#Oracle Property Graph Client 20.4
###インストール

ユーザを`graph`に変更し、ダウンロードしたクライアントパッケージを解凍します。

```sh
sudo su - graph
unzip oracle-graph-client-20.4.0.zip
```

###Auth tokenを入手

Property Graph serverにクライアントから接続する場合、先ずauth tokenを入手する必要があります。

curl コマンドで簡単にauth tokenを入手できます。

```sh
curl -X POST -H 'Content-Type: application/json' -d '{"username": "<DB USER>", "password": "<PASSWORD>"}' <HOST URL>:7007/auth/token

# e.g. curl -X POST -H 'Content-Type: application/json' -d '{"username": "demograph", "password": "<PASSWORD>"}' http://db19h.sub11160238550.graphvcntokyo.oraclevcn.com:7007/auth/token
```

上記の`username`と`password`は、 ユーザネーム`demograph`と作成したパスワードです。
`HOST URL`は、connection stringから抽出可能です。

レスポンスはJSONオブジェクトとして返ってきます。レスポンスをフォーマットすると、auth tokenは

* トークンの中身
* トークンタイプ
* トークンの有効時間

といった3つの要素で構成されているのが確認できます。
次のステップでは、`access_token`の中身が必要になります。
また、有効時間にも注意しましょう。expires_inは秒単位の表記となっており、14400秒なので、４時間後に無効となり、このトークンで作られたセッションも無効となります。

```json
{
  "access_token": "<ENCRYPTED CONTENT>",
  "token_type": "bearer",
  "expires_in": 14400
}
```
#Property Graph Serverに接続
Oracle Property Graph ClientはPGX serverへの複数の接続方法を用意しています。今回は、 Oracle Property Graph Client shellを最初に使っていきます。

未解凍のクライアントパッケージが入っているbinディレクトリに移動しましょう。 

```sh
cd /home/graph/oracle-graph-client-20.4.0/bin

./opg-jshell --base_url <HOST URL>:7007
# e.g. ./opg-jshell --base_url http://db19h.sub11160238550.graphvcntokyo.oraclevcn.com:7007
```

注: セキュリティの観点から、トークンのペーストした際には何も表示されません。ペーストして何も変化がなくても、Enterを押して大丈夫です。



`opg-jshell>`という風にコマンドプロンプトが変化したら、サーバに接続できた証です。

##Graph サンプル - HR
###サンプルデータスキーマ (HR) の準備
[こちらのGitHub](https://github.com/rexzj266/oracle-pgx-on-dbcs-quickstart)からHRスキーマと作成するスクリプトをダウンロードして、pdb1のユーザdemographでHRスキーマを作成して下さい。

```sql
sqlplus demograph/<PASSWORD>@db19h.sub11160238550.graphvcntokyo.oraclevcn.com:1521/pdb1.sub11160238550.graphvcntokyo.oraclevcn.com

@HR_create_hr_objects.sql
```

###property graph表を作成
データベースに接続するためにjshellから下記のスクリプトを実行して下さい。

```java
var jdbcUrl = "jdbc:oracle:thin:@//db19h.sub11160238550.graphvcntokyo.oraclevcn.com:1521/pdb1.sub11160238550.graphvcntokyo.oraclevcn.com"
var user = "demograph"
var pass = "<PASSWORD>"
var conn = DriverManager.getConnection(jdbcUrl, user, pass)

conn.setAutoCommit(false)
```

PGQL接続のために下記のスクリプトを実行して下さい。
このPGQL接続を通じて、用意してある`create.pgql`スクリプトを実行していきます。
このスクリプトで、先ほど作成したHRスキーマのデータベース表も基に property graph 表を作成することができます。

ここから`create.pgql`を入手できます。


```java
var pgql = PgqlConnection.getConnection(conn)
pgql.prepareStatement(Files.readString(Paths.get("/home/graph/create.pgql"))).execute()
```

ここまででVERTEX TABLESとEDGE TABLESなど、いくつかのproperty graph表を作成して参りました。

### データベースから問合せ
ラムダファンクション`query`を定義するために、jshellから下記のスクリプトを実行して下さい。
このファンクションは、後ほど問合せを実行する際に役立ちます。

```java
Consumer < String > query = q -> {
    try (var s = pgql.prepareStatement(q)) {
        s.execute();
        s.getResultSet().print();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
```

下記のスクリプトで

- `hr graph`の頂点の数
- エッジの数
- 降順でマネージャの情報と彼らの給料
について問合せます。

```java
query.accept("select count(v) from hr match (v)")

query.accept("select count(e) from hr match ()-[e]->()")

query.accept("select distinct m.FIRST_NAME, m.LAST_NAME,m.SALARY from hr match (v:EMPLOYEES)-[:WORKS_FOR]->(m:EMPLOYEES) order by m.SALARY desc")
```

### メモリから問い合わせ
Property graph serverにデータをロードすると、問合せのスピードだけでなく、問合せのキャパシティも改善されます。 メモリにロードすることで、より応用的なアルゴリズムを使った問合せもできるようになります。ただのデータからもっと価値のある結果を求めることも可能です。

まず、下記のスクリプトで、メモリ上のgraph構造を定義します。

```java
Supplier <GraphConfig> pgxConfig = () -> {
    return
    GraphConfigBuilder.forPropertyGraphRdbms()
    .setJdbcUrl(jdbcUrl)
    .setUsername(user)
    .setPassword(pass)
    .setName("hr")
    .addVertexProperty("COUNTRY_NAME", PropertyType.STRING)
    .addVertexProperty("DEPARTMENT_NAME", PropertyType.STRING)
    .addVertexProperty("FIRST_NAME", PropertyType.STRING)
    .addVertexProperty("LAST_NAME", PropertyType.STRING)
    .addVertexProperty("EMAIL", PropertyType.STRING)
    .addVertexProperty("PHONE_NUMBER", PropertyType.STRING)
    .addVertexProperty("SALARY", PropertyType.DOUBLE)
    .addVertexProperty("MIN_SALARY", PropertyType.DOUBLE)
    .addVertexProperty("MAX_SALARY", PropertyType.DOUBLE)
    .addVertexProperty("STREET_ADDRESS", PropertyType.STRING)
    .addVertexProperty("POSTAL_CODE", PropertyType.STRING)
    .addVertexProperty("CITY", PropertyType.STRING)
    .addVertexProperty("STATE_PROVINCE", PropertyType.STRING)
    .addVertexProperty("REGION_NAME", PropertyType.STRING)
    .setPartitionWhileLoading(PartitionWhileLoading.BY_LABEL)
    .setLoadVertexLabels(true)
    .setLoadEdgeLabel(true)
    .setKeystoreAlias("alias")
    .build();
}
```

そして、下記のスクリプトで、メモリ上にgraphを作成します。 

```java
var graph = session.readGraphWithProperties(pgxConfig.get())
```

pagerankを求めます。


```java
analyst.pagerank(graph)
```

pagerank結果の最初の１０人の従業員を問合せて、降順表示したい場合はこのようなコードを用います。

```java
session.queryPgql("select m.FIRST_NAME, m.LAST_NAME,m.pagerank from hr match (m:EMPLOYEES) order by m.pagerank desc limit 10").print().close()
```


### `keystore`の準備

`keytool`は、keyの管理とそれらのceritificateをするためのJavaユーティリティです。このJavaユーティリティは、`keystore`を生成するために今回使用します。

下記のコマンドで、`keystores`ディレクトリを作成し、`keystore`を生成します。

```sh
cd
mkdir keystores && cd keystores
keytool -importpass -alias demograph -keystore keystore.p12
```


`Enter keystore password:`と表示されたら、keystore用のパスワードを入力します。その後、`Enter the password to be stored:`と表示されたら、格納したいパスワードを入力します。この記事では、 データベースユーザの`demograph`のパスワードを入力していきます。


### `keystore`で接続
To connect from jshellからデータベースに接続するためには、auth tokenが必要になります。 


```sh
curl -X POST -H 'Content-Type: application/json' -d '{"username": "<DB USER>", "password": "<PASSWORD>"}' <HOST URL>:7007/auth/token

# e.g. curl -X POST -H 'Content-Type: application/json' -d '{"username": "demograph", "password": "<PASSWORD>"}' http://db19h.sub11160238550.graphvcntokyo.oraclevcn.com:7007/auth/token
```
そして、下記のコマンドで、サーバにkeystoreを使った接続を行います。

```sh
cd /home/graph/oracle-graph-client-20.4.0/bin
./opg-jshell --base_url http://db19h.sub11160238550.graphvcntokyo.oraclevcn.com:7007 --secret_store /home/graph/keystores/keystore.p12
```
このステップでは、今手に入れたauth tokenを入力します。
その後、`enter password for keystore /home/graph/keystores/keystore.p12:`と表示されたら、keystore用のパスワードを入力します。



### GraphVizの問合せ

ここまで、コマンドラインインタフェースである`jshell`を使って問合せを行ってきました。
他の方法でも問合せは可能で、ビルドインのグラフィックインターフェースである`GraphViz`も利用可能です。

GraphVizはブラウザベースのインターフェースで、`<HOST URL>:7007/ui`というURLでアクセスが可能です。今回の例ではログイン画面で、usernameは`demograph`、passwordはご自身で設定されたものを入力して下さい。

注:ホストのポートは7007ですが、OCI環境の場合、別途ネットワークの設定からポートを解放しましょう。デフォルトのセキュリティリストのままだとポートが閉じているため、7007番を新たに追加します。

下記のスクリプトで、セッションIDを取得できます。セッションが切れていない限り、そのセッションIDを入力すれば、そのセッションのグラフにアクセスすることができます。

```java
session.getId();
```

ログイン後、下記のようにデフォルトページを確認できます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100411/43cd49e0-74e8-8e92-054e-a6b99b087198.png)

ここでは、複雑な問合せを実行できますし、GraphVizは問合せ結果をインタラクティブなグラフとして表示してくれます。

```java
SELECT *
MATCH (c1)-[e1]->(p1)<-[e2]-(c2)-[e3]->(p2)
WHERE ID(c1) = 'cust_12353'
  AND ID(p2) = 'prod_23166'
  AND ID(c1) != ID(c2)
  AND ID(p1) != ID(p2)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100411/11597b18-3753-2856-cc6a-0bfe720bf07f.png)

また、カスタムセッティングをアップロードすることで、グラフチャートの表現かカスタマイズすることが可能です。例えば、下記のスクリーンショットでは、`highlight.json`と言う設定ファイルをアップロードしました。チャートがさらに直感的に理解できるように表示されています。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100411/047ba6b6-19f3-009e-92b0-08cf6301dd9e.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100411/42bcb84d-245e-c541-5525-0b5e6b239e1b.png)

## まとめ
最後までお読みいただきありがとうございました！
Oracle Property Graphのテクノロジーの基本的な理解と、Oracle Property Graph serverを楽しめる環境をご理解いただけたはずです。

この記事を簡単に振り返ると、Oracle DBCSインスタンスにOracle Property Graph server and clientをセットアップする方法を確認しました。 **※ Property Graph　server and clientは基本的にはどのようなマシーン上にもインストール可能です。**

また、HRとOnline Retailという2つのサンプルを作成し、以下の内容も確認していきました。

- グラフの作成方法
- グラフの問合せ方法
- メモリ上にグラフをロードする方法
- 複雑な問合せを実行する方法
- GraphVizの使い方

## 参考文献

Oracle Property Graphをもっと知りたいと思ったら、下記の参考文献もご参照ください！

- [Oracle as a Property Graph](https://www.oracle.com/database/technologies/spatialandgraph/property-graph-features.html)
- [Oracle Property Graph Developer’s Guide](https://docs.oracle.com/en/database/oracle/oracle-database/20/spgdg/lot.html)
- [ryotayamanaka/oracle-pg](https://github.com/ryotayamanaka/oracle-pg)
- [Oracle Property Graph Server Installation](https://docs.oracle.com/en/database/oracle/oracle-database/20/spgdg/property-graph-overview-spgdg.html#GUID-CCF6BB1E-3C8F-4746-A938-BA3E6EDC9541)