Neo4j:更快的子图着色/标记

Neo4j:更快的子图着色/标记,neo4j,cypher,graph-databases,Neo4j,Cypher,Graph Databases,我有一个包含多个子图的图。目标是将子图中的所有蓝色节点标记为红色,当且仅当该子图中的所有节点均为蓝色时。如果子图中的一个节点具有不同的颜色(绿色),则我们不会更改该子图中节点的颜色 这是我正在使用的查询: MATCH (a:BLUE) WHERE NOT (a)-[*]-(:GREEN) WITH a LIMIT 10000 SET a:RED REMOVE a:BLUE 以下是查询前后的外观: 问题是它速度慢,因为它需要多次遍历同一子图。例如: 要将A标记为红色,它需要穿过A-B-C。然后

我有一个包含多个子图的图。目标是将子图中的所有蓝色节点标记为红色,当且仅当该子图中的所有节点均为蓝色时。如果子图中的一个节点具有不同的颜色(绿色),则我们不会更改该子图中节点的颜色

这是我正在使用的查询:

MATCH (a:BLUE) WHERE NOT (a)-[*]-(:GREEN) WITH a LIMIT 10000 SET a:RED REMOVE a:BLUE
以下是查询前后的外观:

问题是它速度慢,因为它需要多次遍历同一子图。例如:

要将A标记为红色,它需要穿过A-B-C。然后,要标记B,它需要穿过A-B-C。同样,标记C也是如此


我想知道是否有任何方法可以一次性标记子图中的所有节点,而不是一次又一次地访问同一个子图。如果有可能,它将通过许多因素减少查询时间

我还没有使用graph algorithms插件,但是这通常可以比纯Cypher使用更快,尽管所有相关子图中的所有节点都需要进行处理,以便提取到连接子图的一行,因为Neo4j不支持子图查询

过程
apoc.path.subgraphNodes()
尤其有助于从每个节点扩展到整个子图,并且只计算到每个节点的单个路径,而不是计算所有可能的路径

从那里,我们可以按子图中的最小节点分组,只保留一组代表整个子图的节点。这使我们每个子图有一行,这使得我们的谓词可以检查子图中所有节点的颜色,每个子图只运行一次

大概是这样的:

MATCH (n:BLUE) // no need to get subgraphs that don't have blue nodes
CALL apoc.path.subgraphNodes(n, {}) YIELD node
WITH n, collect(node) as nodes, min(id(node)) as minId
WITH minId, head(collect(nodes)) as nodes // now only one row / subgraph
WHERE all(node in nodes where node:BLUE)
UNWIND nodes as node
SET node:RED
REMOVE node:BLUE

首先使用neo4j图形算法插件标记所有子图是否有帮助。。。docs@TomažBratanič在原始用例中,所有早于特定时间戳的节点都标记为蓝色。因此,如果我们可以为整个子图分配子图中最新节点的时间戳,那么union find/connected组件将有所帮助。但这将是非常昂贵的,因为这意味着我需要遍历整个图表。相反,在我的例子中,我将隔离比特定时间戳早的节点,然后只遍历这些节点。@TomažBratanič看起来不错,但这是否可以使用?在使用文档化的名称、参数和收益率时,我的尝试始终没有给我带来任何错误。我在第一个版本中尝试了这些示例,它们都很有效。。。您正在使用neo4j 3.2.x吗?那可能不行,是的,汉克斯。它工作得很好。我尝试使用apoc周期迭代对整个过程进行批处理。***调用apoc.periodic.iterate(“MATCH(n:BLUE)CALL apoc.path.subgraphNodes(n,{})YIELD node WITH n,collect(node)as nodes,min(id(node))as minId WITH minId,head(collect(nodes)),head(collect(nodes))as nodes WHERE all(node in nodes:Marked节点中的节点)返回节点),“展开节点as node SET node:RED移除节点:BLUE”,{batchSize:10000,parallel:true,iterateList:true})***但是我得到了java.lang.OutOfMemoryError错误。基本上是堆溢出。您可能想尝试更改内部和外部查询的边界。可能只在开始的蓝色节点上尝试迭代,
MATCH(n:blue)
,并对batchSize稍作调整,因为堆需要容纳对批处理中每个:BLUE节点的整个子图的扩展。