2021年6月11日金曜日

neo4jの拡張プラグイン apoc.export.csv.query の例2

sample.csv を cypher-shell で読んで、田中さんの友達グループ Tanaka_G.csvを出力する。

sample.csv
id,name,add,job,relation
a001,田中,東広島,販売,a002
a002,山本,北広島,販売,a003
a003,佐藤,久留米,飲食,a001
a004,山崎,,建設,a002
a005,村上,東久留米,販売,a002
a006,広田,南大東島,醸造,a001

$ sudo neo4j start
$ cypher-shell -u XXXXX -p XXXX

//sample.csvからノードを作成
neo4j@neo4j> LOAD CSV WITH HEADERS FROM 'file:///sample.csv' AS row
             MERGE (p:Person{ID:coalesce(row.id,"Unknown"), NAME:coalesce(row.name,"Unknown"),ADD:coalesce(row.add,"Unknown"), JOB:coalesce(row.job,"Unknown"), REL:coalesce(row.relation,"Unknown")});

//リレーションシップの作成
neo4j@neo4j> load csv with headers from "file:///sample.csv" as row
             match (p1:Person{ID:row.id})
             match (p2:Person{ID:row.relation})
             merge (p1)-[r:Know]->(p2);
0 rows available after 262 ms, consumed after another 0 ms
Created 6 relationshi

// 田中さんグループ Tanaka_G.csv への出力。[:Know]の'*'はrelation shipが続く限り全部。
neo4j@neo4j> with "match (a{NAME:'田中'})-[:Know*]->(b)
             return b.NAME as name, b.ADD as address" as Friends
             call apoc.export.csv.query(Friends, "Tanaka_G.csv",{})
             yield file     // これをしないと
             return file;   // returnが無いエラー
+----------------+
| file           |
+----------------+
| "Tanaka_G.csv" |
+----------------+

1 row available after 21 ms, consumed after another 8 ms

別のターミナルから出力ファイルを見てみる
$ cat Tanaka_G.csv
"name","address"
"山本","北広島"
"佐藤","久留米"
"田中","東広島"
neo4j@neo4j> match (n) detach delete n;
neo4j@neo4j>:quit
$ sudo neo4j stop

---------------------
neo4jブラウザで同じことをやってみる。

// systemctlからneo4jを起動すると、起動表示はなくなる。
$ systemctl start neo4j
ブラウザから localhost:7474 Username:XXXXX Password:XXXXX

nao4j$ LOAD CSV WITH HEADERS FROM 'file:///sample.csv' AS row
       MERGE (p:Person{ID:coalesce(row.id,"Unknown"), NAME:coalesce(row.name,"Unknown"),ADD:coalesce(row.add,"Unknown"), JOB:coalesce(row.job,"Unknown"), REL:coalesce(row.relation,"Unknown")}); // Ctrl+Enter

neo4j$ LOAD CSV WITH HEADERS FROM "file:///sample.csv" AS row
       MATCH (p1:Person{ID:row.id})
       MATCH (p2:Person{ID:row.relation})
       MERGE (p1)-[r:Know]->(p2);  // Ctrl+Enter

// 本題とはちがうけどGraph表示
// neo4j$ MATCH (p1)-[r:Know]->(p2) RETURN p1,r,p2;


neo4j$ MATCH (a{NAME:'田中'})-[r:Know*]->(b) RETURN b.NAME AS name, b.ADD AS address; // Enter
ここで、[ Export CSV ]をクリック

// 本題とはちがうけどGraph表示
// neo4j$ MATCH (a{NAME:'田中'})-[r:Know*]->(b) RETURN a,r,b;
 
ターミナルから出力ファイルを見てみる
$ cat export.csv
name,address
山本,北広島
佐藤,久留米
田中,東広島
neo4j$ MATCH (n) DETACH DELETE n;
Clear local data
$ systemctl stop neo4j

以上、素人の個人的実験でした。

2021年6月10日木曜日

neo4jの拡張プラグイン apoc.export.csv.query の例1

sample.csv を cypher-shell で読んで、ADD(住所)が'広島'の人の名前を result.csvに出力する。

sample.csv
id,name,add,job,relation
a001,田中,東広島,販売,a002
a002,山本,北広島,販売,a003
a003,佐藤,久留米,飲食,a001
a004,山崎,,建設,a002
a005,村上,東久留米,販売,a002
a006,広田,南大東島,醸造,a001
 
$ sudo neo4j start
$ cypher-shell -u neo4j -p XXXX

// coalesce(a,"b") は、セルがaならaを返す。なければ文字列bを返す
neo4j@neo4j> LOAD CSV WITH HEADERS FROM 'file:///sample.csv' AS row
             MERGE (p:Person{ID:coalesce(row.id,"Unknown"), NAME:coalesce(row.name,"Unknown"),ADD:coalesce(row.add,"Unknown"), JOB:coalesce(row.job,"Unknown"), REL:coalesce(row.relation,"Unknown")});

neo4j@neo4j> call apoc.export.csv.query("match (a:Person) where a.ADD contains '広島' return a.NAME, a.ADD", "result.csv", {});
+-------------------------------------------------------------------------------------------------------------------------------------+
| file         | source               | format | nodes | relationships | properties | time | rows | batchSize | batches | done | data |
+-------------------------------------------------------------------------------------------------------------------------------------+
| "result.csv" | "statement: cols(2)" | "csv"  | 0     | 0             | 4          | 1    | 2    | 20000     | 1       | TRUE | NULL |
+-------------------------------------------------------------------------------------------------------------------------------------+

1 row available after 23 ms, consumed after another 63 ms
別ターミナルからファイルを見てみる
$ cat /var/lib/neo4j/import/result.csv
"a.NAME","a.ADD"
"田中","東広島"
"山本","北広島"
neo4j@neo4j> match (n) detach delete n;
neo4j@neo4j>:quit
$ sudo neo4j stop // 終了
===========================================
同じ例を neo4jブラウザでやってみる

$ sudo neo4j start
ブラウザ localhost:7474 Username: XXXXX Pssword:XXXXXX

neo4j$ LOAD CSV WITH HEADERS FROM 'file:///sample.csv' AS row
       MERGE (p:Person{ID:coalesce(row.id,"Unknown"), NAME:coalesce(row.name,"Unknown"),ADD:coalesce(row.add,"Unknown"), JOB:coalesce(row.job,"Unknown"), REL:coalesce(row.relation,"Unknown")}); //Ctrl+Enter

neo4j$ MATCH (a:Person) WHERE a.ADD CONTAINS '広島' RETURN a.NAME, a.ADD; //Enter
上のバーから Expor CSV をクリック

出力をターミナルから見てみる
$ cat export.csv
a.NAME,a.ADD
田中,東広島
山本,北広島
$ MATCH (n) DETACH DELETE n; してneo4j 左の赤っぽいアイコンで終了。$ sudo neo4j stop
 
===========================
結局、文字列指定のダブルクォートの差以外は、同じ結果でした。
以上、まるっきり素人の私には、いろいろ覚えなくてもいい方を選ぶ。
 
環境 Debian 10, neo4j 4.2.7 community 版, Cypher-Shell 4.2.7

2021年6月9日水曜日

neo4jの拡張プラグイン apocの設定

動機:
neo4jで検索したリレーションやノードは'TEXT'としてコピペはできるけど、ファイルとして出力したい → 'apoc'という拡張プラグインで csv出力できるらしい。

環境:
Debian 10, neo4j 4.2.7 community 版, Cypher-Shell 4.2.7

設定:
neo4j community インストール済ならば、/var/lib/neo4j/labs/apoc-4.2.0.4-core.jar がすでに入っている。ただし同 README.txt記述の設定と export設定が必要。

(neo4j サーバが動いてない状態で)
1) $ sudo cp /var/lib/neo4j/labs/apoc-4.2.0.4-core.jar /var/lib/neo4j/plugins/
2) /etc/neo4j/neo4j.conf 262行目あたりに追記
  dbms.security.procedures.unrestricted=apoc.*
3) /etc/neo4j/neo4j.conf 最後辺りに追記
  apoc.export.file.enabled=true
  apoc.import.file.enabled=true

chown neo4j:neo4j apoc-4.2.0.4-core.jar
chmod 755 apoc-4.2.0.4-core.jar
の手順記事もあった。やらなくても動いた。

動作確認:
$ sudo neo4j start // neo4jサーバ起動
$ cypher-shell -u neo4j -p XXXX //cypher-shell起動
neo4j@neo4j> return apoc.version();  //⇠neo4jブラウザからでも可
+----------------+
| apoc.version() |
+----------------+
| "4.2.0.4"      |
+----------------+   // 受け付けるっぽい
neo4j@neo4j> merge (a:Person{name:'Yamada', age:tointeger(30), address:'Yamanashi'}); //ノード作成して実験
neo4j@neo4j> call apoc.export.csv.all("out_node.csv", {}); //⇠neo4jブラウザからでも可 out_node.csvに出力
別ターミナルから デフォルト import先の /var/lib/neo4j/import を見てみる。
(neo4j.confで import先を変更してる場合は、そちらに出力される)
$ ls -l /var/lib/neo4j/import/out_node.csv
-rw-r--r-- 1 root root out_node.csv
$ cat out_node.csv
"_id","_labels","address","age","name","_start","_end","_type"
"0",":Person","Yamanashi","30","Yamada",,,       // なんか OKみたい

neo4j@neo4j> match (n) detach delete n; // 以上、クリーニング
neo4j@neo4j> :exit    // cypher-shell終了
$ sudo neo4j stop     // neo4jサーバ停止

まとめ:
CALL apoc.export.csv.all("出力ファイル名.csv", {}); が得られた。
他に apoc.export.csv.query というプロシージャもある。

出力ファイル先 import を /etc/neo4j/neo4j.confのdbms.directories.import=/var/lib/neo4j/import を /home/USER/...などに変更してる場合、出力.csvが rootでしかrwできないのは不便かも...どこで変えるんだろう?
 
本末転倒
apoc設定しなくても、neo4jブラウザの場合、returnで返すようなコードの場合は、右上のバーから csv, json, png, svg でファイルが保存できる。