Neo4j的性能与周期

时间:2016-11-16 16:44:15

标签: performance graph neo4j traversal

我有一个相对较大的neo4j图,有7百万个顶点和5百万个关系。

当我试图找出一个节点的子树大小时,neo4j被卡在遍历600,000个节点中,其中只有130个是唯一的。 它是因为周期而做到的。 看起来只有在遍历整个图形到最大深度后才应用distinct

是否有可能以某种方式改变这种行为?

查询是:

match (a1)-[o1*1..]->(a2) WHERE a1.id = '123' RETURN distinct a2

1 个答案:

答案 0 :(得分:2)

您可以迭代地逐步完成子图a"层"在避免多次重新处理同一节点的同时,使用APOC程序apoc.periodic.commit。该过程迭代地处理查询,直到它返回0.

以下是此技术的示例。它:

  • 使用临时TempNode节点来跟踪迭代之间的几个重要值,其中一个最终将包含子图中节点的消息ID(" root&#34除外) ;节点的ID,因为您的问题的查询也将其遗漏了。)
  • 假设您关注的所有节点共享相同的标签Foo,并且您在Foo(id)上拥有索引。这是为了加快MATCH操作,并不是绝对必要的。

步骤1:创建TempNode(使用MERGE,重用现有节点,如果有的话)

WITH '123' AS rootId
MERGE (temp:TempNode)
SET temp.allIds = [rootId], temp.layerIds = [rootId];

步骤2:执行迭代(获取所有子图节点)

CALL apoc.periodic.commit("
  MATCH (temp:TempNode)
  UNWIND temp.layerIds AS id
  MATCH (n:Foo) WHERE n.id = id
  OPTIONAL MATCH (n)-->(next)
  WHERE NOT next.id IN temp.allIds
  WITH temp, COLLECT(DISTINCT next.id) AS layerIds
  SET temp.allIds = temp.allIds + layerIds, temp.layerIds = layerIds
  RETURN SIZE(layerIds);
");

第3步:使用子图ID

MATCH (temp:TempNode)
// ... use temp.allIds, which contains the distinct ids in the subgraph ...