创建大量关系时内存不足

时间:2015-07-20 08:43:25

标签: neo4j cypher

我是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)"
 ^

是否有可能以这种方式在大量现有节点之间创建关系,还是需要采用不同的方法?

1 个答案:

答案 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更新节点。