我是Neo4J的新手,我想尝试一下我从MySQL导出的一些数据。我已使用neo4j console
运行社区版,并且我使用neo4j-shell
命令行客户端输入命令。
我有2个CSV文件,用于创建2种类型的节点,如下所示:
USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM "file:/tmp/updates.csv" AS row
CREATE (:Update {update_id: row.id, update_type: row.update_type, customer_name: row.customer_name, .... });
CREATE INDEX ON :Update(update_id);
USING PERIODIC COMMIT
LOAD CSV WITH HEADERS FROM "file:/tmp/facts.csv" AS row
CREATE (:Fact {update_id: row.update_id, status: row.status, ..... });
CREATE INDEX ON :Fact(update_id);
这为我提供了大约650,000个更新节点和21,000,000个Fact节点。
索引在线后,我尝试在节点之间创建关系,如下所示:
MATCH (a:Update)
WITH a
MATCH (b:Fact{update_id:a.update_id})
CREATE (b)-[:FROM]->(a)
此操作因OutOfMemoryError
而失败。我相信这是因为Neo4J在事务完成之前不提交事务,将其保留在内存中。
我该怎么做才能防止这种情况发生?我已阅读有关USING PERIODIC COMMIT
的内容,但看起来这只在阅读CSV时有用,因为它在我的案例中不起作用:
neo4j-sh (?)$ USING PERIODIC COMMIT
> MATCH (a:Update)
> WITH a
> MATCH (b:Fact{update_id:a.update_id})
> CREATE (b)-[:FROM]->(a);
QueryExecutionKernelException: Invalid input 'M': expected whitespace, comment, an integer or LoadCSVQuery (line 2, column 1 (offset: 22))
"MATCH (a:Update)"
^
是否有可能以这种方式在大量现有节点之间创建关系,还是需要采用不同的方法?
答案 0 :(得分:6)
内存不足异常是正常的,因为它会尝试一次提交所有内容并且因为你没有提供它,我假设java堆设置被设置为默认值(512m)。
但是,你可以用一种分页来批处理过程,在这种情况下我只想使用MERGE而不是CREATE:
MATCH (a:Update)
WITH a
SKIP 0
LIMIT 50000
MATCH (b:Fact{update_id:a.update_id})
MERGE (b)-[:FROM]->(a)
在每批次之后修改SKIP和LIMIT,直到达到650k更新节点。