Neo4J:创建关系时超出GC开销限制

时间:2016-09-12 02:01:32

标签: neo4j

代码是:

load csv with headers from "https://data.cityofnewyork.us/api/views/feu5-w2e2/rows.csv?accessType=DOWNLOAD" as row
create (n:Contact) set n=row;

load csv with headers from "https://data.cityofnewyork.us/api/views/tesw-yqqr/rows.csv?accessType=DOWNLOAD" as row
create (n:Building) set n=row;

create index on :Contact(RegistrationID);

create index on :Building(RegistrationID);

然后,当我尝试创建一个关系时,它会升级到8GB ram并最终超时并且应用程序将死于此:

MATCH (b:Building),(c:Contact)
where b.RegistrationID = c.RegistrationID
create (b)-[:CONTACTS_FOR]->(c)

Windows 7/64位i7-3770,32GB内存......

1 个答案:

答案 0 :(得分:1)

如果您的数据集很大,您不想执行任何在整个标签上运行的查询,您几乎可以确保在neo4j日志中看到内存峰值,超时以及最终出现OutOfMemory错误。您应该执行这些查询的顺序是:

1)制作索引。

2)合并其中一个数据集并合并提前这样的关系,并使用定期提交,这样就不必将整个结果保存在内存中[编辑:自从RegistrationID不是一个独特的属性,为它创建一个替代节点,因此可以预先建立你的部分关系]:

USING PERIODIC COMMIT 500
load csv with headers from "https://data.cityofnewyork.us/api/views/tesw-yqqr/rows.csv?accessType=DOWNLOAD" as row
CREATE (b:Building) SET b=row
MERGE (i:RegistrationID {RegistrationID: row.RegistrationID})
MERGE (b) - [:CONTACTS_FOR] -> (i)

3)然后,合并到其他数据集中。您现有的索引将确保如果您使用MERGE而不是CREATE,那么您将获得您在上一步中返回的已创建的RegistrationID节点:

USING PERIOD COMMIT 500
load csv with headers from "https://data.cityofnewyork.us/api/views/feu5-w2e2/rows.csv?accessType=DOWNLOAD" as row
CREATE (c:Contact) SET c = row
MERGE (i:RegistrationID {RegistrationID: row.RegistrationID})
MERGE (i) - [:CONTACT_FOR] -> (c)

要通过构建查询联系人,请使用*运算符,如下所示:

MATCH (b:Building) WHERE <whatever conditions you want>
WITH b
MATCH (b) <- [:CONTACT_FOR*2] - (c)
RETURN c

现在,如果您的数据已经存在并且您不想重新加载,那么您必须在查询中使用SKIP和LIMIT来一次只处理一个块:

MATCH (b:Building)
WITH b
SKIP 0
LIMIT 500
MATCH (c:Contact) WHERE c._id = b._id
MERGE (b) - [:CONTACTS_FOR] -> (c)

然后反复运行,每次将SKIP和LIMIT向上移动500。

即使你的机器理论上能够处理那么大的查询,neo4j 都会设置它运行的JVM的限制,这可能会阻止你利用它。尝试提出一个使用大量小迭代查询而不是一个大问题的解决方案,它通常会更有效。