加快Cypher的合并运营

时间:2016-09-20 10:45:25

标签: neo4j cypher

我有2个不同的节点,标签为 Class Parent 。这些节点与 hasParents 关系相关联。有400万个Class节点,700K个Parent节点。我想在Class节点之间创建一个同级关系。我做了以下查询:

Match (A:Class)-[:hasParents]-> (B:Parents) <-[:hasParents]-(C:Class) Merge (A)-[:Sibling]-[C]

此查询需要很长时间才能完成。我已在class_idparent_id节点的ClassParents属性中编入索引。我使用的是Neo4j 2.1.6版。任何提高速度的建议。

1 个答案:

答案 0 :(得分:0)

首先,索引不会帮助查询,因为查询中的任何地方都没有引用属性。

使用700K Parent个节点和4M Class个节点,每个父节点平均有5.7个类。在一个父级下有5个类,有15个Sibling关系,因此要为整个图创建超过10M的关系。

对于一个交易,很多,您几乎可以保证达到OutOfMemory错误。

为避免这种情况,您应该将更改批量处理为几个较小的事务。

我会使用标记标签来管理进展。首先,标记所有父母:

MATCH (p:Parent) SET p:ToProcess

然后,重复选择剩余要处理的节点的子集,并连接兄弟姐妹:

MATCH (p:ToProcess)
REMOVE p:ToProcess
WITH p
LIMIT 1000
OPTIONAL MATCH (p)<-[:hasParents]-(c:Class)
WITH p, collect(c) AS children
FOREACH (c1 IN children |
    FOREACH (c2 IN filter(c IN children WHERE c <> c1) |
        MERGE (c1)-[:Sibling]-(c2)))
RETURN count(p)

当查询返回已处理的父项数时,您只需重复它直到它返回0.此时,没有父项具有ToProcess标签。