PGX - Groovyでのプロパティ・グラフ分析手順

# はじめに
### 動作環境について
- Oracle Cloud Infrastructure (OCI)上に作成した Database - Virtual Machines
- Oracle Database 18.2 Enterprise Edition High Performance
　（プロパティ・グラフの利用にはHigh Performance以上のEditionが必要）

### PGX (Parallel Graph AnalytiX) とは
インメモリのグラフ分析フレームワークです。ページランクや次数中心性等々のグラフを分析するアルゴリズムが多数組み込まれています。

### プロパティ・グラフとは
Oracle Database 12c R2よりSpatial and Graph Optionに組み込まれたグラフ・データベース機能です。プロパティ・グラフ化することでデータ間の関係やプロパティの検出、分析が可能となります。

### Groovyとは
JVM上で動作するスクリプト言語です。Spatial and Graphのサポートに組み込みのGroovy Shellが含まれています。Groovyを活用することでインタラクティブな分析が可能となります。

# プロパティ・グラフの分析手順
### 環境準備
```
$ sqlplus / as sysdba
     --プロパティ・グラフ利用のための設定
SQL> ALTER SESSION SET CONTAINER=pdb1;
SQL> ALTER SYSTEM SET max_string_size=extended SCOPE=SPFILE;
SQL> connect / as sysdba
SQL> ALTER PLUGGABLE DATABASE pdb1 CLOSE;
SQL> ALTER PLUGGABLE DATABASE pdb1 OPEN UPGRADE;
SQL> ALTER SESSION SET CONTAINER=pdb1;
SQL> @?/rdbms/admin/utl32k.sql
SQL> connect / as sysdba
SQL> ALTER PLUGGABLE DATABASE pdb1 CLOSE;
SQL> ALTER PLUGGABLE DATABASE pdb1 OPEN;
SQL> connect / as sysdba
SQL> ALTER SESSION SET CONTAINER=pdb1;
SQL> @?/md/admin/catopg.sql
SQL> sqlplus / as sysdba
SQL> ALTER USER mdsys ACCOUNT UNLOCK;
SQL> ALTER SESSION SET CONTAINER=pdb1;
     --必要に応じてユーザー作成
SQL> CREATE USER pguser IDENTIFIED BY XXXXX;
SQL> ALTER USER pguser QUOTA UNLIMITED ON users;
SQL> GRANT connect, resource TO pguser;
SQL> exit
```

### Groovy Shellの起動
```
$ cd $ORACLE_HOME/md/property_graph/dal/groovy/
$ sh ./gremlin-opg-rdbms.sh
```

### プロパティ・グラフへのロード
"connections"という名称のグラフにサンプルとして提供されているフラットファイルをロードします。

```
opg-oracledb> cfg = GraphConfigBuilder.forPropertyGraphRdbms() \
opg-oracledb> .setJdbcUrl("jdbc:oracle:thin:@xxx.xxx.xxx.xxx:xxx/pdb01.xxxxx.xxxxx.oraclevcn.com") \
opg-oracledb> .setUsername("pguser").setPassword("XXXXX") \
opg-oracledb> .setName("connections") .setMaxNumConnections(8)\
opg-oracledb> .addVertexProperty("name", PropertyType.STRING)\
opg-oracledb> .build();
opg-oracledb> opg = OraclePropertyGraph.getInstance(cfg);
opg-oracledb> opgdl = OraclePropertyGraphDataLoader.getInstance();
opg-oracledb> opgdl.loadData(opg, new FileInputStream("../../data/connections.opv"), new FileInputStream("../../data/connections.ope"), 2, 1000, true, null);
opg-oracledb> opg.countVertices();
==>78
opg-oracledb> opg.countEdges();
==>164

```

### PGXの実行とPGQLによる探索
プロパティ・グラフをPGXにロードし、PageRankを求めてその上位者同士の繋がりを[PGQL](http://pgql-lang.org/)（Property Graph Query Languageの略、SQLに似たプロパティ・グラフに対するクエリ言語。）より取得します。

```

opg-oracledb> session = Pgx.createSession("session-id-1");
opg-oracledb> g = session.readGraphWithProperties(cfg);
opg-oracledb> analyst = session.createAnalyst();
opg-oracledb> analyst.pagerank(g);
==>VertexProperty[name=pagerank,type=double,graph=connections]
 　★↑pagerankというプロパティがノードに付与される
opg-oracledb> g.queryPgql("SELECT m.name, m.pagerank, n.name, n.pagerank WHERE (m)->(n) ORDER BY m.pagerank desc, n.pagerank desc").print(3)
+------------------------------------------------------------------+
| m.name  | m.pagerank          | n.name    | n.pagerank           |
+------------------------------------------------------------------+
| B - san | 0.05552150985655605 | H - san   | 0.025788783613479208 |
| B - san | 0.05552150985655605 | C - san   | 0.01975629533879598  |
| B - san | 0.05552150985655605 | P - san   | 0.019438763162232517 |
+------------------------------------------------------------------+

```
実際のデータは人名等が含まれているので一応マスクしてます。

# リファレンス
[Oracle Database CoreTech Seminar 12.2 Oracle Spatial and Graph]
(http://otndnld.oracle.co.jp/ondemand/od12c-oct2016/07_DB12201_coretech_SpatialandGraph_forOTN_v1.8.pdf)
[How to enable Oracle Database Cloud Service with Property Graph Capabilities](https://blogs.oracle.com/oraclespatial/how-to-enable-oracle-database-cloud-service-with-property-graph-capabilities)
[Oracle Database Release 18 Property Graph Developer’s Guide](https://docs.oracle.com/cd/E96517_01/spgdg/index.html)