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" } }, ~中略 ]
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)での実装が絶対嬉しいでしょう。