fbpx

neo4j-etlコマンドラインインターフェース(CLI)の紹介 #neo4j

この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。

neo4j-etlは、いわゆるCLIでRDBからデータをエクスポートしてからダイレクトにNeo4jへインポートするツールです。弊社の木内がNeo4j ETL DeskTop,Neo4j ETLの紹介のようにGUIで行うNeo4j ETLを紹介していますが、今回はその続編としてCLIで行うNeo4j ETLをご紹介します。

  • Neo4j ETLは、GUI(Neo4j DeskTop)で行う方法と、CLI(neo4j-etl)で行う2つの方法がある。
  • JDBCを利用し、Oracle、MS SQLServer、MS SQLServer、Derby、Cassandra、SAP Hana、MySQL、PostgreSQLなどに対応している。
  • Neo4j ETLは、基本的に指定されたスキーマの全データをマイグレーション対象にする。
  • ただし、ソースDBとNeo4jとの間にマッピングファイルを挟んで、不要なデータのフィルターや、サブグラフの範囲、属性、ラベル名やタイプ名の変更などができる。

これから、簡単な検証を実行してみます。

[参照サイト]
https://neo4j-contrib.github.io/neo4j-etl/
https://neo4j.com/developer/neo4j-etl/

事前準備

検証環境構成

  • CentOS7.5
  • JDK8
  • MySQL5.7
  • Neo4j3.4.10
  • neo4j-etl-cli-1.2.1
  • JDBCドライバー(mysql-connecor-java-5.1.25-3)

Oracle JDKインストール

今回は、Oracle JDK(jdk-8u191-linux-x64.rpm)をインストールしています。

[参照サイト]
https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

[メモ]

Oracle JDK利用は筆者の好みです。OpenJDK8が既にインストールされている場合、この手順はスキップしても構いません。

$ sudo  rpm -qa |grep openjdk
java-1.8.0-openjdk-headless-1.8.0.191.b12-0.el7_5.x86_64
java-1.8.0-openjdk-1.8.0.191.b12-0.el7_5.x86_64
$ sudo  yum remove java-1.8.0-openjdk-headless-1.8.0.191.b12-0.el7_5.x86_64 java-1.8.0-openjdk-1.8.0.191.b12-0.el7_5.x86_64
$ sudo rpm -Uvh jdk-8u191-linux-x64.rpm

MySQLインストール

MySQL5.7をインストールします。

[参照サイト]
https://dev.mysql.com/doc/mysql-yum-repo-quick-guide/en/

$ sudo  vi /etc/yum.repos.d/mysql-community.repo
[mysql57-community]
name=MySQL 5.7 Community Server
baseurl=http://repo.mysql.com/yum/mysql-5.7-community/el/7/$basearch/
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
$ sudo yum install mysql-community-server mysql-community-devel mysql-utilities
$ mysql --version
mysql  Ver 14.14 Distrib 5.7.24, for Linux (x86_64) using  EditLine wrapper
$ sudo systemctl start mysqld
$ sudo systemctl status mysqld
$ sudo grep 'temporary password' /var/log/mysqld.log
2018-11-29T05:40:56.657776Z 1 [Note] A temporary password is generated for root@localhost: oGiCj+:py4<em>y
$ mysql -uroot -p
Enter password: oGiCj+:py4</em>y
mysql>
mysql>ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyPassword';
mysql> CREATE DATABASE IF NOT EXISTS northwind;
mysql> CREATE user 'etluser'@'%' IDENTIFIED BY 'MyPassword'';
mysql> GRANT ALL ON northwind.* TO 'etluser'@'%';

MySQLへデモDBのインストール(northwind)

northwindは、RDBモデルからGDBモデルへのマイグレーションを想定したデモ用データベースです。

[参照サイト]
https://github.com/pthom/northwind_psql/blob/master/northwind.sql

ご覧の通り、このデモ用データベースは、PostgreSQL版しか存在しません。ここで紹介しているMySQL版は、筆者がコンバートしたものです。

3つのファイルをダウンロードし、MySQLを実行するユーザのホームディレクトリにアップロードしてください。

northwind-ddl.sql.txt
northwind-dml.sql.txt
northwind-foreign-key.sql.txt

northwindデータベースを作成します。

mysql> use northwind
Database changed
mysql> source northwind-ddl.sql.txt
~
mysql> source northwind-dml.sql.txt
~
--neo4j-etlでは、外部キーに従ってGDBモデルのリレーションシップを作成します。
--外部キーが存在しないと、リレーションシップが存在しないGDBモデルになってしまいます。
mysql> soruce northwind-foreign-key.sql.txt
~
--データ件数をチェックします。
--customer_customer_demoとcustomer_demographicsは、そもそもデータが存在しないので0件で間違いありません。
mysql> 
SELECT count(<em>) FROM customer_customer_demo
UNION ALL
SELECT count(</em>) FROM customer_demographics
UNION ALL
SELECT count(<em>) FROM employee_territories
UNION ALL
SELECT count(</em>) FROM order_details
UNION ALL
SELECT count(<em>) FROM orders
UNION ALL
SELECT count(</em>) FROM customers
UNION ALL
SELECT count(<em>) FROM products
UNION ALL
SELECT count(</em>) FROM shippers
UNION ALL
SELECT count(<em>) FROM suppliers
UNION ALL
SELECT count(</em>) FROM territories
UNION ALL
SELECT count(<em>) FROM us_states
UNION ALL
SELECT count(</em>) FROM categories
UNION ALL
SELECT count(<em>) FROM region;
+----------+
| count(</em>) |
+----------+
|        0 |
|        0 |
|       49 |
|     2155 |
|      830 |
|       91 |
|       77 |
|        6 |
|       29 |
|       53 |
|       51 |
|        8 |
|        4 |
+----------+

Neo4j Server EEインストール

今回は、1ヵ月限定のNeo4j Enterprise Editionを利用します。

[参照サイト]
https://neo4j.com/download-center/#releases

$ tar zxvf neo4j-enterprise-3.4.10-unix.tar.gz
$ sudo mv neo4j-enterprise-3.4.10 /var/lib/neo4j
$ sudo vi conf/neo4j.conf
dbms.connectors.default_listen_address=10.0.0.6
$ sudo bin/neo4j start

neo4j-etlインストール

最新版のneo4j-etlをタウンロードし、$NEOJ_HOME配下にデプロイします。

[参照サイト]
https://github.com/neo4j-contrib/neo4j-etl

$ wget https://github.com/neo4j-contrib/neo4j-etl/releases/download/1.2.1/neo4j-etl-cli-1.2.1-release.zip
$ unzip neo4j-etl-cli-1.2.1-release.zip
$ cd neo4j-etl-cli-1.2.1
$ ls
bin  docs  lib  LICENSE.txt  README.adoc  THIRD-PARTY.txt
$ sudo cp bin/* /var/lib/neo4j/bin/
$ sudo cp lib/neo4j-etl.jar /var/lib/neo4j/lib/

JDBCドライバインストール

neo4j-etlは、JDBCドライバ―でRDBに接続します。
今回は、MySQLのJDBCドライバーをインストールします。

[参照サイト]
http://dev.mysql.com/downloads/connector/j/
https://centos.pkgs.org/7/centos-x86_64/mysql-connector-java-5.1.25-3.el7.noarch.rpm.html

$ wget http://mirror.centos.org/centos/7/os/x86_64/Packages/mysql-connector-java-5.1.25-3.el7.noarch.rpm
$ sudo rpm -Uvh mysql-connector-java-5.1.25-3.el7.noarch.rpm
$ ls /usr/share/java/mysql-connector-java.jar
$ sudo cp /usr/share/java/mysql-connector-java.jar /var/lib/neo4j/lib/mysql-connector-java.jar

Neo4j ETL(CLI)の実行

マッピングファイル作成

マッピングファイルとは、文字通り、RDBモデルをGDBモデルに置き換えるためのマップです。

マッピングファイルは、指定したRDBのスキーマと外部キー、他のオプションに従ってRDBからGDBへのマップを作成します。

  • GDBモデルは、このマッピングファイルの定義に従って構築されます。
  • マッピングファイルの中身は、些か複雑はJSON型式の定義ですが、規則性を持っているので出力してからカスタマイズできます。

では、マッピングファイルを作成します。

$ mkdir /tmp/northwind
$ export NEO4J_HOME=/var/lib/neo4j
$ $NEO4J_HOME/bin/neo4j-etl help
$ $NEO4J_HOME/bin/neo4j-etl help generate-metadata-mapping 
$ $NEO4J_HOME/bin/neo4j-etl generate-metadata-mapping \
  --rdbms:url jdbc:mysql://localhost:3306/northwind?useSSL=false \
  --rdbms:user etluser --rdbms:password MyPassword \
  --rdbms:schema northwind \
  --output-mapping-file /tmp/northwind/mapping.json

マッピングファイルの中身は、特別なフィルターオプションを指定していない限り、--rdbms:schemaで指定したRDBのスキーマが全体が対象になります。

[ {
  "name" : "NODE_northwind.customers_d4778131-09bc-49d2-a8cf-a1b664c7ba52",
  "schema" : "northwind",
  "graph-object-type" : "Node",
  "sql" : "SELECT <code>northwind</code>.<code>customers</code>.<code>customer_id</code> AS <code>customer_id</code>, <code>northwind</code>.<code>customers</code>.<code>customer_id</code> AS <code>customer_id</code>, <code>northwind</code>.<code>customers</code>.<code>fax</code> AS <code>fax</code>, <code>northwind</code>.<code>customers</code>.<code>address</code> AS <code>address</code>, <code>northwind</code>.<code>customers</code>.<code>postal_code</code> AS <code>postal_code</code>, <code>northwind</code>.<code>customers</code>.<code>region</code> AS <code>region</code>, <code>northwind</code>.<code>customers</code>.<code>contact_title</code> AS <code>contact_title</code>, <code>northwind</code>.<code>customers</code>.<code>country</code> AS <code>country</code>, <code>northwind</code>.<code>customers</code>.<code>contact_name</code> AS <code>contact_name</code>, <code>northwind</code>.<code>customers</code>.<code>city</code> AS <code>city</code>, <code>northwind</code>.<code>customers</code>.<code>phone</code> AS <code>phone</code>, <code>northwind</code>.<code>customers</code>.<code>company_name</code> AS <code>company_name</code>, \"Customer\" AS <code>_NODE_LABEL_</code> FROM <code>northwind</code>.<code>customers</code>",
  "mappings" : [ {
    "column" : {
      "type" : "CompositeColumn",
      "table" : "customers",
      "schema" : "northwind",
      "role" : "PrimaryKey",
      "columns" : [ {
        "type" : "SimpleColumn",
        "role" : "Data",
        "table" : "customers",
        "schema" : "northwind",
        "name" : "customer_id",
        "alias" : "customer_id",
        "sql-data-type" : "VARCHAR",
        "column-value-selection-strategy" : "SelectColumnValue"
      } ]
    },
    "field" : {
      "type" : "Id",
      "name" : "",
      "id-space" : "northwind.customers"
    }
  },
~中略
]

nortwind-mapping-all.json.

neo4j-etlの実行

neo4j-etlは、マッピングファイルに従ってRDBのデータをCSVにエクスポートしてから、GDBへインポートします。インポートする時は、neo4j-import、neo4j-shell、cypher-shell、java bolt driverなどのオプションを選ぶことができます。

今回は、cypher-shellを利用します。このオプションだと、Neo4jサーバは起動中である必要があります。

$ echo '{"multiline-fields":"true"}' > /tmp/northwind/options.json
$ export NEO4J_HOME=/var/lib/neo4j
$ $NEO4J_HOME/bin/neo4j-etl export \
  --rdbms:url jdbc:mysql://localhost:3306/northwind?autoReconnect=true  \
  --rdbms:user etluser --password MyPassword \
  --rdbms:schema northwind \
  --using cypher:direct \
  --neo4j:url bolt://10.0.0.10:7687 \
  --neo4j:user neo4j --neo4j:password MyPassword \
  --import-tool $NEO4J_HOME/bin \
  --options-file /tmp/northwind/options.json \
  --mapping-file /tmp/northwind/mapping.json \
  --csv-directory $NEO4J_HOME/import \
  --debug --force

neo4j-etlコマンドを実行してから、Neo4jブラウザーを開き、メタグラフを出力してみましょう。

CALL db.schema()

次のようなメタグラフが表示できればETLは成功しています。
このメターグラフは、デフォルトのマッピングファイルによるGDBモデルです。おそらく、不要なサブグラフは取り込みたくないとか、名称を変えたい場合があると思います。

GDBモデルのカスタマイズには、2つの方法があります。

  • マッピングファイルを作成するコマンドにオプションを一杯付けて、ぴったりのマッピングファイルを作成する。
  • ほぼオプションなしのマッピングファイル(mapping.json)を作成し、不要なものは削除し、気に要らない名称は変更する。

次のGDBモデルは、マッピングファイルを編集してETLを実行したものです。必要なサブグラフだけを残し、リレーションシップの名称をCATEGORIESからPART_OFに変更しています。


northwind-mapping-customized.json

まとめ

1度限りのマイグレーションの場合は、Neo4j Desktopでもneo4j-etlでも大差ないかも知れませんが、夜間バッチなどで繰り替えしてGDBを入れ替えるようなケースでは、CLI(neo4j-etl)での実装が絶対嬉しいでしょう。

Author

モダンアーキテクチャー基盤のソリューションアーキテクトとして活動しています。

[著書]
・Amazon Cloudテクニカルガイド―EC2/S3からVPCまで徹底解析
・Amazon Elastic MapReduceテクニカルガイド ―クラウド型Hadoopで実現する大規模分散処理
・Cypherクエリー言語の事例で学ぶグラフデータベースNeo4j
・Neo4jを使うグラフ型データベース入門(共著)
・RDB技術者のためのNoSQLガイド(共著)

leeの記事一覧

新規CTA