Neo4j 循环性能
Neo4j performance with cycles
我有一个比较大的 neo4j 图,有 700 万个顶点和 500 万个关系。
当我试图找出一个节点的子树大小时,neo4j 被困在遍历 600,000 个节点中,其中只有 130 个是唯一的。
它这样做是因为循环。
看起来它只在遍历整个图到最大深度后才应用 distinct
。
是否可以通过某种方式改变这种行为?
查询是:
match (a1)-[o1*1..]->(a2) WHERE a1.id = '123' RETURN distinct a2
您可以通过使用 APOC 过程 apoc.periodic.commit 一次迭代地遍历子图 a "layer",同时避免多次重新处理同一节点。该过程迭代地处理一个查询,直到它 returns 0.
这是此技术的一个示例。它:
- 使用临时
TempNode
节点来跟踪迭代之间的几个重要值,其中一个最终将包含子图中节点的不同 ID("root" 除外节点的 id,因为你的问题的查询也遗漏了它)。
- 假设您关心的所有节点共享相同的标签
Foo
,并且您在 Foo(id)
上有一个索引。这是为了加快 MATCH
操作,并非绝对必要。
第 1 步:创建临时节点(使用 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 ...
我有一个比较大的 neo4j 图,有 700 万个顶点和 500 万个关系。
当我试图找出一个节点的子树大小时,neo4j 被困在遍历 600,000 个节点中,其中只有 130 个是唯一的。
它这样做是因为循环。
看起来它只在遍历整个图到最大深度后才应用 distinct
。
是否可以通过某种方式改变这种行为?
查询是:
match (a1)-[o1*1..]->(a2) WHERE a1.id = '123' RETURN distinct a2
您可以通过使用 APOC 过程 apoc.periodic.commit 一次迭代地遍历子图 a "layer",同时避免多次重新处理同一节点。该过程迭代地处理一个查询,直到它 returns 0.
这是此技术的一个示例。它:
- 使用临时
TempNode
节点来跟踪迭代之间的几个重要值,其中一个最终将包含子图中节点的不同 ID("root" 除外节点的 id,因为你的问题的查询也遗漏了它)。 - 假设您关心的所有节点共享相同的标签
Foo
,并且您在Foo(id)
上有一个索引。这是为了加快MATCH
操作,并非绝对必要。
第 1 步:创建临时节点(使用 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 ...