Oracle Graph を Docker 上で構築（前編）

![docker1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410176/c361cc46-f06f-5036-641f-9c52bd332ec1.jpeg)
ここでは、Oracle Database の最新機能の一つ Oracle Graph を無料で手軽に試すため、手元の Docker コンテナ上に構築する方法を紹介します。Oracle Database の初回起動など多少の時間がかかりますが、待っていれば終わりますので是非お試しください。

まずは Oracle Graph のアーキテクチャの概観は次の通りです。Oracle Database 単独でもグラフ・データベースとして機能しますので（2-tier deployment）まず前編ではこの構成を扱います。[後編](https://qiita.com/ryotayamanaka/items/090dd06236e7ca5d75c5)では Graph Server というインメモリのグラフ分析フレームワークを追加することで、超高速なクエリやグラフアルゴリズムの実行を可能にします。

![](https://user-images.githubusercontent.com/4862919/138631261-105c0795-3942-483c-9e01-f28417bf6d59.png)

それなら Oracle Database は要らないから Graph Server だけを使いたいよ、という方もいらっしゃるかもしれません。そういう方法がないわけではない（ハックしていただけると思う）のですが、Graph Server でも Oracle Database のユーザー認証を用いることで、できる限りシームレスなデータ連携と企業用途のセキュリティを実現しようというのが Oracle Graph の思想です。

## データベースの構築

もしも既に利用できる Oracle Database（バージョン 12.2 以降）をお持ちであればそちらをお使い頂くこともできますので、その場合は次項「Oracle Graph の有効化」に進まれてください。

もしも Docker 上に構築するのであれば Oracle Container Registry から [Express Edition (XE 21c)](https://container-registry.oracle.com/ords/f?p=113:4:16154335611961:::4:P4_REPOSITORY,AI_REPOSITORY,AI_REPOSITORY_NAME,P4_REPOSITORY_NAME,P4_EULA_ID,P4_BUSINESS_AREA_ID:803,803,Oracle%20Database%20Express%20Edition,Oracle%20Database%20Express%20Edition,1,0&cs=3WNcqvHY1EFg0-dsgaqBS9V21R_f3lCziMJZdRp5h54TQLzDGzYo43KXb6enZwo098qJlUyZ5B6yd_1Qmoburxw) のイメージを入手することをおすすめします。ご存じない方も多いかと思いますが Express Edition を使えば、サイズの制限があるものの（2CPU スレッド、2GB RAM、12GB のユーザーデータ）小さなデータベースであれば Oracle Database のほとんどの機能を無料で使うことができます。もちろん Oracle Graph も含まれています！

まずはイメージを pull してください。展開されると 6GB くらいあります。

```
docker pull container-registry.oracle.com/database/express:21.3.0-xe
```

コンテナを起動するとこれに含まれるデータベースが数十秒で起動しますので、ログを追跡しておきます。

```
docker run -d --name database -p 1521:1521 -v $HOME:/host-home \
container-registry.oracle.com/database/express:21.3.0-xe
docker logs -f database
```

以下のようなメッセージが出てきたら、データベースへの接続が可能です。

```
#########################
DATABASE IS READY TO USE!
#########################
```

Control + C でログ表示を終了して、次のコマンドでパスワードを設定します。

```
docker exec database ./setPassword.sh Welcome1
```

SQL クライアント（ sqlplus ）を用いて管理ユーザーとして接続します。

```
docker exec -it database sqlplus sys/Welcome1@xepdb1 as sysdba
```

コンテナを再起動しても、同様に接続できることを確かめてください。

```
docker stop database
docker start database
```

## パッケージのダウンロード

さて、ここからいよいよ Oracle Graph の話になります。

Oracle Graph を有効化するためのパッチ（PL/SQL スクリプト）を[こちらのサイト](https://www.oracle.com/database/technologies/spatialandgraph/property-graph-features/graph-server-and-client/graph-server-and-client-downloads.html)からダウンロードします。いずれかのパッケージを選択すると、Oracle アカウントでのログインが要求されて、Oracle Software Delivery Cloud というところに飛ばされます。

このチュートリアルで必要になる次の 2 つのファイルにチェックを入れてダウンロードします。

- Oracle Graph PL/SQL Patch (V1032115-01.zip)
- Oracle Graph PGQL Plugin for SQLcl (V1032114-01.zip)

![Screen Shot 2022-12-05 at 15.52.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410176/e6eca205-e251-e065-7243-641dbc989092.png)

Oracle Download Manager なるものが現れてダウンロードを開始します。
![Screen Shot 2022-12-05 at 15.53.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410176/b5adc4e4-d064-8419-a502-f9acfebfa24c.png)

## Oracle Graph の有効化

ここでは、データベースに PL/SQL パッチを適用して Oracle Graph を有効化します。

Oracle Graph Client for PL/SQL の Zip ファイル（ V1032115-01.zip ）がダウンロードできたらコンテナからアクセスできる適当な場所に展開してください。ここでは $HOME/oracle-graph としておきます。

```
cd $HOME/oracle-graph
unzip V1032115-01.zip
unzip oracle-graph-plsql-22.4.0.zip -d oracle-graph-plsql
```

コンテナ上の SQL クライアントに接続します。

```
docker exec -it database sqlplus sys/Welcome1@xepdb1 as sysdba
```

スクリプトを実行します。ここではホストの $HOME がコンテナの /host-home にマウントされています。

```
@/host-home/oracle-graph/oracle-graph-plsql/19c_and_above/opgremov.sql
@/host-home/oracle-graph/oracle-graph-plsql/19c_and_above/catopg.sql
exit
```

## ユーザーの作成

コンテナ上の SQL クライアントに接続します。

```
docker exec -it database sqlplus sys/Welcome1@xepdb1 as sysdba
```

graphuser というデータベース・ユーザーを作成して必要な権限を与えます。

```sql
CREATE USER graphuser
IDENTIFIED BY Welcome1
DEFAULT TABLESPACE users
TEMPORARY TABLESPACE temp
QUOTA UNLIMITED ON users;

GRANT
  alter session 
, create procedure 
, create sequence 
, create session 
, create table 
, create trigger 
, create type 
, create view
, graph_developer -- This role is required for using Graph Server
TO graphuser;

exit
```

新しいユーザーで接続できることを確認します。

```
docker exec -it database sqlplus graphuser/Welcome1@xepdb1
```

## SQLcl の準備

sqlplus は PGQL を扱う機能がないため、PGQL プラグインが提供されている SQL クライアントの SQLcl を準備します。

先程ダウンロードした Zip ファイル (V1032114–01.zip) を回答して得られる oracle-graph-sqlcl-plugin-21.4.0.zip と次に作成する Dockerfile を同じディレクトリに配置します。

```
$ unzip V1032114-01.zip
Archive:  V1032114-01.zip
  inflating: oracle-graph-sqlcl-plugin-22.4.0.zip
$ vi Dockerfile
```

Dockerfile のサンプルです。

```dockerfile:Dockerfile
FROM openjdk:12-oracle
ARG VERSION_OPG
RUN yum -y install unzip \
 && yum clean all
RUN curl -s https://download.oracle.com/otn_software/java/sqldeveloper/sqlcl-latest.zip > sqlcl-latest.zip
RUN unzip sqlcl-latest.zip
RUN chmod 755 sqlcl/bin/sql
ADD oracle-graph-sqlcl-plugin-${VERSION_OPG}.zip .
RUN unzip oracle-graph-sqlcl-plugin-${VERSION_OPG}.zip -d sqlcl/lib/ext \
 && rm oracle-graph-sqlcl-plugin-${VERSION_OPG}.zip
ENV PATH=sqlcl/bin:$PATH
CMD sql
```

イメージをビルドします。

```
docker build . -t sqlcl-pgql --build-arg VERSION_OPG=22.4.0
```

sql コマンドでこのコンテナを都度実行できるように alias を設定します。

```
alias sql='docker run --rm -it sqlcl-pgql sql'
```

同じホスト上のコンテナで起動しているデータベースに接続します。Docker の動作している環境によっては host.docker.internal というホスト名が使えないことがありますので、その場合にはホストの IP アドレスを指定してください。

```
sql graphuser/Welcome1@host.docker.internal:1521/xepdb1
```

## グラフの作成

SQLcl を PGQL モードに切り替えできることを確認します。

```
SQL> pgql auto on

PGQL Auto enabled for graph=[null], execute=[true], translate=[false]
PGQL>
```

PGQL クエリでグラフを作成します。

```
CREATE PROPERTY GRAPH graph1;
```

グラフにふたつのノードとその間のエッジを追加します。クエリをペーストした際にうまく実行されない場合には、`/`（再実行のコマンド）を入力して実行できる場合があります。

```
INSERT INTO graph1 VERTEX v
LABELS (PERSON) PROPERTIES (v.id = 'p1', v.NAME = 'Alice');

INSERT INTO graph1 VERTEX v
LABELS (CAR) PROPERTIES (v.id = 'd1', v.BRAND = 'Toyota');

INSERT INTO graph1 EDGE e BETWEEN src AND dst
LABELS (HAS) PROPERTIES (e.SINCE = 2017)
FROM MATCH ( (src), (dst) ) ON graph1
WHERE src.id = 'p1' AND dst.id = 'd1';

COMMIT;
```

グラフのパターンで「Alice の持っている車」を検索してみます。

```
SELECT p.NAME, LABEL(h), c.BRAND, h.SINCE
FROM MATCH (p)-[h:HAS]->(c:CAR) ON graph1
WHERE p.NAME = 'Alice';
```
```
NAME     LABEL(h)    BRAND     SINCE 
________ ___________ _________ ________ 
Alice    HAS         Toyota    2017
```

お疲れ様でした。今回の内容はここまでとしたいと思います。

この記事では Docker コンテナ上で Oracle Graph を構築して使い始めるための手順を紹介しました。Oracle Database 単体をグラフ・データベースとして使う方法があるということもご理解頂けたかと思います。

一方で、Oracle Graph の強みである、表データの宣言的な変換や高性能な Graph Server との連携など、Oracle Graph 自体についてはまだまだ紹介できていませんので、[次回（後編）](https://qiita.com/ryotayamanaka/items/090dd06236e7ca5d75c5)以降に記載していきたいと思います。