0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

GraphDBを学ぶ(3)neo4j:ノードとエッジの作成

Posted at

TL;DR

  • neo4jを使ってGraphDBの扱い方を学びます
    • その第1段として,手作業でデータを登録し,検索する方法を紹介します
  • RDBMSベンチマークTPC-Hのテーブルを参考に,neo4jにノードを登録してみます(nation, regionのみ)

作業方針

  • データベースベンチマークTPC-HをMySQLで実行する(TPC-H v2.18.0)を参考に, sf=0.01 のサイズでデータベースを作成してデータの確認に使用します
    • sf=1でやったらデータの登録が終わらなるかもしれいないので,この記事では小さい(sf=0.01)データを扱います
  • TPC-Hのテーブルを見ながら,neo4jにデータを(最初は手作業で)投入,検索をしてみます
  • CUIのneo4jクライアントneo4j-clientを使用します

シンプルなデータ登録(Nation, Regionテーブルを参考に)

  • まず,投入するデータについて考えます
    • TPC-Hのテーブル群の中で,Nationテーブル(25エントリ),Regionテーブル(5エントリ)は,has-manyの関係にあり,scale factorにかかわらず各テーブルのエントリ数が固定です.
      • 使いやすそうな関係なので,neo4j(Cypher)のテストに使います
    • regionテーブルのエントリをグラフのノードへ登録する際には,Webクライアントで実験します
    • nationテーブルは,neo4j-clientを使います

nr.jpg

regionノードの登録

MariaDB [sf1]> select * from region;
+-------------+-------------+---------------------------------------------------------------------------------------------------------------------+
| R_REGIONKEY | R_NAME      | R_COMMENT                                                                                                           |
+-------------+-------------+---------------------------------------------------------------------------------------------------------------------+
|           0 | AFRICA      | lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to  |
.....<snip>.....
|           4 | MIDDLE EAST | uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl        |
+-------------+-------------+---------------------------------------------------------------------------------------------------------------------+
5 rows in set (0.00 sec)
  • 5つのRegion(地域)が登録されています
  • Regionテーブルは,R_NAME (fixed text, size 25)およびR_COMMENT (variable text, size 152)という,2つの属性を持つエントリからなります
  • そこで,neo4jに,各エントリをノードとして登録してみます

Cypherクエリでノードを1つ登録

  • R_NAMEが"AFRICA"のregionノードを登録してみます
CREATE
(:region{R_REGIONKEY:0, R_NAME:"AFRICA",R_COMMENT:"lar deposits. blithely final packages cajole. regular waters are final requests. regular accounts are according to"});
  • WebUIのコンソールに入力する場合は,以下のようにコマンドを記述してエンターキーか,再生ボタンを押します
  • (おまけ)ノードを削除したい場合は,該当するノードをMATCH句で取り出してDELETEします
MATCH (r :region{R_REGIONKEY:0}) DELETE r;
  • 以下のようなログ出力が行われ,ノードの登録ができたログが出力されます
Added 1 label, created 1 node, set 2 properties, completed after 12 ms.

Cypherクエリで複数ノードをまとめて登録

  • create句に加えて,ノードの情報を列挙すると,複数のノードをまとめて登録することができます.この操作で,残りのノードを登録します.
create
(:region{R_REGIONKEY:1, R_NAME:"AMERICA",R_COMMENT:"hs use ironic, even requests. s"}),
(:region{R_REGIONKEY:2, R_NAME:"ASIA",R_COMMENT:"ges. thinly even pinto beans ca"}),
(:region{R_REGIONKEY:3, R_NAME:"EUROPE",R_COMMENT:"ly final courts cajole furiously final excuse"}),
(:region{R_REGIONKEY:4, R_NAME:"MIDDLE EAST",R_COMMENT:"uickly special accounts cajole carefully blithely close requests. carefully final asymptotes haggle furiousl"});
  • WebUIでは以下のように入力されることになります

登録ノードの確認

  • match句ですべてのノード(条件無しでマッチ)を返す(表示する)クエリを発行します
match(n) return n
  • WebUIの場合,以下のようなグラーフとして表示されます
    • マウスでノードをドラッグできるので楽しいです
    • neo4j-clientでは行が表示されます

nationノードの登録

  • 前項のregionと同様の方法で,nationもノード登録します
  • しかし,プロンプトで登録していくのは面倒なので,csvファイルから取り込みます

MySQLからテーブルをcsv出力する

  • 1ノードずつ登録するのは面倒なので,まとめて登録する方法を考えます
  • mysqlのコマンドで,nationテーブルをcsvに出力します(参考:MySQLのSELECT文でcsvを出力する)
select N_NATIONKEY, N_NAME, N_COMMENT from nation
    into outfile '/tmp/nation.csv'
    fields terminated by ','
    optionally enclosed by '"';
  • /tmp/nation.csvに,以下のような国名とコメントのリストが得られます
cat /tmp/nation.csv

"ALGERIA"," haggle. carefully final deposits detect slyly agai"
.....<snip>.....
"UNITED STATES","y final packages. slow foxes cajole quickly. quickly silent platelets breach ironic accounts. unusual pinto be"

csvファイルのノードをまとめてneo4jに登録する

  • インポートしたいファイルをインポート用ディレクトリ(デフォルトでは/var/lib/neo4j/import)に置いて,load csvコマンドで,取り込むことができます.
    • csvファイルを1行ずつ読み込み,カンマでsplitして配列(line)に分解します
    • 配列の対応する要素(line[0]など)を,ノードの属性に設定して CREATE します
neo4j-client -u neo4j localhost

neo4j>
LOAD CSV FROM 'file:///nation.csv' AS line
CREATE (:nation {N_NATIONKEY: toInteger(line[0]), N_NAME: line[1], N_COMMENT: line[2]});

Created 25 nodes, set 75 properties, added 25 labels
0 rows returned in 106ms (rendered after 126ms)
  • 25個のノードが作られた旨のメッセージが出れば成功です
  • WebUIで確認すると,regionとnationの2種類のラベルでノードが合計30個できていることを確認できます

ノード間の関係の登録

  • regionとnationの関係(nationはregionにある)を登録します

Cypherクエリで関係を登録する

  • nationの各ノードは,いずれかのregionが設定されます
    • RDBMSの文脈では,nationテーブルのN_REGIONKEYに対応するR_REGIONKEYの値を持つregionのエントリがあります
    • その国(nation)はあの地域(region)に「ある」という関係をATという名前で示すことにします
  • ノード間の関係は,以下のようなCypherクエリで設定できます
    • 以下の例では,N_NATIONKEY=0のnationノード(アルジェリア)がR_REGIONKEY=0のregionノード(アフリカ)にある,という関係を設定しています
neo4j>
MATCH(n:nation{N_NATIONKEY: 0}), (r:region{R_REGIONKEY: 0})
CREATE (n)-[:AT]->(r);
  • WebUIから,関係の接続関係を見ることができます
  • (おまけ)関係の削除は,以下のように,特定の関係に名前(b)を付けて,DELETEを実行します
neo4j>
MATCH (n:nation{N_NATIONKEY: 0}) -[b:AT]-> 
(r:region{R_REGIONKEY: 0}) DELETE b;

関係をnationのcsvファイルから設定する

  • コマンド入力は面倒なので,各nation.csvの外部キー情報を使って,どのregionに属しているかの関係を設定します
neo4j>
LOAD CSV FROM 'file:///nation.csv' AS line
  MATCH (n:nation{N_NATIONKEY: toInteger(line[0])})
  MATCH (r:region{R_REGIONKEY: toInteger(line[2])})
CREATE (n)-[:AT]->(r);

Created 25 relationships);
0 rows returned in 83ms (rendered after 89ms)
  • WebUIから,国と地域がそれぞれノードとして存在し,国が地域に所属している関係をみることができます

参考

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?