Cypher Tips
Delete Huge node with all its relationships
例えば、あるノードだけ削除したいとします。 一般的にはこのようなCypherを書きます。 数千件のレベルだとこれでノードとそれに紐づいているリレーションシップが削除されます。 ところが、数百万件だと一度に処理しようとするので処理は終わらないしメモリーもオーバーフローします。
MATCH (n:SomeNode) DETACH DELETE n;
そこで、APOCのライブラリーを使ってバッチサイズを設定し小さな単位で処理します。 parallelはメモリーによって選択してください。 これで、億単位の削除も小さなメモリーで高速に処理できます。
CALL apoc.periodic.iterate(
"MATCH (n:SomeNode) RETURN n",
"DETACH DELETE n",
{batchSize:10000, parallel:true});
LOAD CSV with Transaction
CSVからNeo4jにデータをロードする時にはLOAD CSVを使います。 LOAD CSVはデータベースがアクティブな時でも使えるコマンドです。
これは、ヘッダーが無いCSVの例です。
LOAD CSV FROM 'file:///artists.csv' AS line
CREATE (:Artist {name: line[1], year: toInteger(line[2])})
件数が多くなるとトランザクションを使うと処理はとっても早くなります。 Neo4j 4.3まではこのような書き方です。
:auto USING PERIODIC COMMIT 2000
LOAD CSV FROM 'file:///artists.csv' AS line
CREATE (:Artist {name: line[1], year: toInteger(line[2])})
Neo4j 4.4からは CALL TRANSACTIONS が使えます。
:auto LOAD CSV FROM 'file:///artists.csv' AS line
CALL {
WITH line
CREATE (:Artist {name: line[1], year: toInteger(line[2])})
} IN TRANSACTIONS OF 2000 ROWS
Simple existential subquery
WHEREの条件にリレーションシップを含める時の書き方です。
MATCH (:Node {name:'a'})-[:REL1|REL2*..10]->(n:Node)
WHERE (n)-[:REL2]->(:Node)
RETURN n;
上記は分かりやすいのですが、将来的に変わるということなので EXISTSを使って書き換えます。
MATCH (:Node {name:'a'})-[:REL1|REL2*..10]->(n:Node)
WHERE EXISTS {
MATCH (n)-[:REL2]->(:Node)
}
RETURN n;