AWSでNeo4jを使ってみる

**この記事は、Neo4j v4.0(2020-01)に合わせて更新しています！**


EC2インスタンスにグラフDB Neo4jをインストールしてみました。

グラフDBとは、RDBでは処理困難な、非常に複雑なネットワーク状のデータ処理に特化したデータベースです。

* 1つのSQL文で結合関係が10個以上発生するような処理
* SQLでは、書き切れないような処理（遅くて困っているものも含めて）
* そもそも、関係性が複雑すぎてデータベース設計自体が困難

グラフDBのデータモデルは、文字通り、グラフ（頂点と辺）です。RDBと違って結合関係を永続化します。辺(WRITE)の前後に始点の終点のIDを持たせて、インデックスのような働きをさせています（トラバーサルと言います）。
![datamodel4type.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69832/0445d0d6-5334-a8f2-e74c-a45c55235741.png)


RDBのように結合関係を紐解く必要がないために、とても複雑な処理を簡明な構文で書けるし、高速処理が可能です。

ネットワーク状のデータとは、どのようなデータでしょうか。

そもそも、すべてのデータは何かしらの繋がりを持ち、本質的にネットワークの形状をしています。そこにあるのは、データ間の繋がりの密度が高いか低いか、階層が深いか浅いか、だけの問題です。そのなかでグラフDBは、繋がりの密度が高く、階層が深いデータ処理に向いています。

グラフモデルの場合、データベース設計がとても簡単です。エンジニアでなくても、自分が担当している業務のフローは書けると思います。それが、そのままデータベースのスキーマになります。

![datamodel-of-network&IT.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69832/2ccab304-9607-d1fe-1696-448b6d5b7d1a.png)
Displaying 17 nodes, 63 relationships.


>このスキーマは、オンラインサンドボックスの「Network and IT Management」のデータモデルです。
https://neo4j.com/sandbox/

複雑なネットワーク構造のデータをSQLで処理しようとすると、いわゆる「ジョインボム(join bomb)」の問題に直面します。想像を絶する長さでノロノロしたクエリのことです。それでも、SQLで書き切れるなら幸いな方です。プロシジャーを書く羽目になるかも知れません。その時点でリアルタイム処理は遠のいてしまいます。

Neo4jは、とても複雑なネットワーク状のデータ処理に最適化された、Cypher（サイファー）というクエリ言語を使ってデータ処理を行います。

# Neo4jのインストール
##事前準備
[参考]
https://neo4j.com/docs/operations-manual/current/installation/linux/rpm/

Community AMIから調達しています(CentOS7 baseで検索)

* CENTOS7-BASE-8.0 - ami-19b1237f
* General purpose　t3.large　2vCPU/8G
* Default VPC
* Auto-assign Public IP Enable

>Amazon LinuxってJava 11のインストールがややこしいですね。Neo4jの公式マニュアルには、"amazon-linux-extras enable java-openjdk11"とか書いていますが使えませんでした。
MarketplaceでNeo4jバンドルのAMIで調達してみたらUbuntuでNeo4j v3.5でした。

セキュリティグループに「tcp 7474,7687」を追加します。

最新のNeo4j 4.xは、Java 11が必要です。

|Neo4j 3.x|Neo4j 4.x|
|---------|---------|
|Java 8   | Java11  |


EC2インスタンスを起動し、サーバーへログインします(centos/秘密鍵)

JavaとNeo4jのバージョンを確認してみます。

```
# java -version
-bash: java: command not found

# yum install java-11-openjdk-devel -y

# java -version
openjdk version "11.0.6" 2020-01-14 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.6+10-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.6+10-LTS, mixed mode, sharing)
```

## Neo4jインストール
Neo4j3.5からRPMパッケージが使えるようになりました。
ここでは、「Red Hat, CentOS, Fedora」をベースに解説します。

```
# rpm --import https://debian.neo4j.com/neotechnology.gpg.key
# cat <<EOF>  /etc/yum.repos.d/neo4j.repo
[neo4j]
name=Neo4j RPM Repository
baseurl=https://yum.neo4j.com/stable
enabled=1
gpgcheck=1
EOF
```

コミュニティ版のインストール

```
# yum install neo4j-4.0.0 -y
```

コマシャル版のインストール（30日間無償で使えます）

```
# yum install neo4j-enterprise-4.0.0 -y
```

ファイル配置を確認します。

```
# ls /etc/neo4j/
neo4j.conf

# ls /var/lib/neo4j
certificates  data  import  plugins

# ls /usr/bin/{neo4j,neo4j-admin,cypher-shell}
/usr/bin/cypher-shell  /usr/bin/neo4j  /usr/bin/neo4j-admin
```

##インストール後の環境設定
リモートからNeo4jブラウザーに接続するためには、neo4j.conf」の設定が必要です。
次のように「リッスンアドレス」をアンコメントします。


/etc/neo4j/neo4j.conf

```
dbms.connectors.default_listen_address=<local IP address>
```

次のように初期パスワードを設定します。これは、初期ログイン時に許されるものです。

```
# neo4j-admin set-initial-password your_password
```

運用中にadminユーザーのパスワードを忘れてしまった場合のリセット方法は、次のURLを参照してください。
https://neo4j.com/docs/operations-manual/current/configuration/password-and-user-recovery/


##Neo4jの起動

Neo4jを起動します。

```
# systemctl start neo4j
# systemctl status neo4j
● neo4j.service - Neo4j Graph Database
   Loaded: loaded (/usr/lib/systemd/system/neo4j.service; disabled; vendor preset: disabled)
   Active: active (running) since Sun 2020-03-01 14:43:41 UTC; 17s ago
 Main PID: 12073 (java)
   CGroup: /system.slice/neo4j.service
           mq12073 /usr/bin/java -cp /var/lib/neo4j/plugins:/etc/neo4j:/usr/share/neo4j/lib/*:/var/lib/neo4j/plugins/* -server -XX:+UseG1GC -XX:-OmitStackTraceInFastThrow -XX:+AlwaysPreT...

Mar 01 14:43:42 ip-172-31-12-73.ap-northeast-1.compute.internal neo4j[12073]: 2020-03-01 14:43:42.647+0000 WARN  Use of deprecated setting dbms.directories.certificates. Legacy ...upported.
Mar 01 14:43:42 ip-172-31-12-73.ap-northeast-1.compute.internal neo4j[12073]: 2020-03-01 14:43:42.649+0000 WARN  Use of deprecated setting dbms.connectors.default_listen_address...n_address
Mar 01 14:43:42 ip-172-31-12-73.ap-northeast-1.compute.internal neo4j[12073]: 2020-03-01 14:43:42.667+0000 INFO  ======== Neo4j 4.0.0 ========
Mar 01 14:43:42 ip-172-31-12-73.ap-northeast-1.compute.internal neo4j[12073]: 2020-03-01 14:43:42.675+0000 INFO  Starting...
Mar 01 14:43:45 ip-172-31-12-73.ap-northeast-1.compute.internal neo4j[12073]: SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
Mar 01 14:43:45 ip-172-31-12-73.ap-northeast-1.compute.internal neo4j[12073]: SLF4J: Defaulting to no-operation (NOP) logger implementation
Mar 01 14:43:45 ip-172-31-12-73.ap-northeast-1.compute.internal neo4j[12073]: SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Mar 01 14:43:48 ip-172-31-12-73.ap-northeast-1.compute.internal neo4j[12073]: 2020-03-01 14:43:48.017+0000 INFO  Bolt enabled on 0.0.0.0:7687.
Mar 01 14:43:48 ip-172-31-12-73.ap-northeast-1.compute.internal neo4j[12073]: 2020-03-01 14:43:48.018+0000 INFO  Started.
Mar 01 14:43:49 ip-172-31-12-73.ap-northeast-1.compute.internal neo4j[12073]: 2020-03-01 14:43:49.425+0000 INFO  Remote interface available at http://localhost:7474/
```

## Neo4jへログイン
Webブラウザーから、次のように接続します。

```
PublicIP:7474
```

初期画面では、サーバーで設定したパスワードを入力します(neo4j/your_password)。

![neo4j-install-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69832/c312035b-18b4-0211-ea49-d83c3e063069.png)

次のようにワーキングパネルが表示されます。ここまで表示できたらインストールは成功です。

![neo4j-install-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69832/6a875642-50b3-0840-01af-29bbfe0bca9f.png)


## 演習用の映画データベース作成
Neo4jブラウザーへ、次のように入力し、実行します（右上の実行パターンをクリック）。

```
:play movie graph
```

映画データベースの紹介画面が表示されたら右に移動します。そして、次のような映画データベース作成用のCypherクエリ文が表示されたら、枠のなかをクリックし、コマンドラインにコピーしてから実行します。

![neo4j-install-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69832/5a5dded9-2134-82dd-c182-db808ef5e7c4.png)

次のようなグラフが表示されたらデータベース作成は成功です。

![movie-graph.png](https://qiita-image-store.s3.amazonaws.com/0/69832/4868ec58-2240-c16e-d1a0-65cbce839e25.png)


## Neo4jのデータ処理
Neo4jのデータ処理は、GUI及びCUIを適切にミックスして行います。

Keanu Reevesさんが出演した映画をグラフとして出力してみます。

```
MATCH (actor:Person {name:'Keanu Reeves'})-[r:ACTED_IN]->(movie)
RETURN actor,movie 
```


![keanu-movie-1.png](https://qiita-image-store.s3.amazonaws.com/0/69832/f2e55263-de27-94f9-e465-5fda36df519e.png)

グラフの中身はテキストとしても出力できます。

```
MATCH (actor:Person {name:'Keanu Reeves'})-[r:ACTED_IN]->(movie)
RETURN actor.name,movie.title 
```

![keanu-movie-2.png](https://qiita-image-store.s3.amazonaws.com/0/69832/0468afa3-a703-89eb-3bf6-b2c1b959916c.png)

Cypherを勉強してみたい方は、こちらのオンライントレーニングがお薦めです。
https://neo4j.com/graphacademy/online-training/introduction-to-neo4j/

筆者から言わせると、Cypherはアート（芸術作品）です。

##Neo4jのストップ
Neo4jをストップします。

```
# systemctl stop neo4j
```

以上、Neo4j v4.x(2020-01)のインストール手順でした。