Neo4j-Cypher:快速找到最大的断开子图

Neo4j-Cypher:快速找到最大的断开子图,neo4j,Neo4j,我有一个有一百万个节点的图。其中有许多断开连接的子图。我想知道最大的不连通子图是什么 例如,在这个图示例中,我们得到了三个断开连接的子图,因此对于这种情况,输出将是7 我试过了,但花了很长时间 match p = ()-[*]-() return MAX(length(p)) as l order by l desc limit 1 您的查询将只返回两个独立节点之间的最长路径,而不是最大连接子图的大小 不幸的是,Neo4j目前没有任何对子图操作的本机支持,我认为APOC过程在这里也没有任何东

我有一个有一百万个节点的图。其中有许多断开连接的子图。我想知道最大的不连通子图是什么

例如,在这个图示例中,我们得到了三个断开连接的子图,因此对于这种情况,输出将是7

我试过了,但花了很长时间

match p = ()-[*]-() return MAX(length(p)) as l order by l desc limit 1

您的查询将只返回两个独立节点之间的最长路径,而不是最大连接子图的大小

不幸的是,Neo4j目前没有任何对子图操作的本机支持,我认为APOC过程在这里也没有任何东西

在Cypher中可以找到子图,但我能想到的查询速度不快,性能也不高,而且可能会在大型图中超时。这里有一个,同样,这是不推荐的,它可能会超时,但如果它起作用,太棒了:

MATCH (n)-[*0..]-(subgraphNode)
WITH n, COUNT(DISTINCT subgraphNode) as subSize
RETURN MAX(subSize)
如果这是一个经常运行的查询,或者每隔一次,而不是只运行一次,那么我推荐一种跟踪子图的方法

虽然我可以给出一种创建子图跟踪的方法,但在图操作(合并子图、划分为更小的子图或创建新的子图)中保持这种更新的方法肯定会更复杂,并且您可能需要某种Java扩展来执行事务后处理来维护这一点

此外,这种方法最好在没有写操作发生的维护窗口期间进行

最终目标是为每个断开连接的子图附加一个:子图节点,这将使将来对子图的操作更加容易,包括查找最大的断开连接的子图

实现该目标的总体方法是首先标记图形中的所有节点(使用类似于:Unprocessed的标签),然后在对:Unprocessed nodes的批处理查询中,找到它们所属的整个断开连接的子图,将单个:子图节点附加到该子图,然后从子图中删除:Unprocessed标签

因此,首先,标记数据库中的所有节点:

MATCH (n)
SET n:Unprocessed
接下来是批处理操作。您将希望使用APOC过程来允许批处理(这也将利用在处理时从:Unprocessed标签中删除整个子图的优势…我们不希望冗余地对子图执行操作)

编辑

与使用变量关系匹配相比,我发现了一种收集子图节点的更快方法。APOC的路径扩展器功能,使用节点的全局唯一性,应该执行得更快。以下是为使用此方法而修改的相关查询

CALL apoc.periodic.commit("
// only process a batch of :Unproccessed nodes at a time
MATCH (n:Unprocessed)
WITH n LIMIT {limit}
// subgraphNode will be all nodes in the subgraph including n
CALL apoc.path.expandConfig(n,{bfs:true, uniqueness:"NODE_GLOBAL"}) 
  YIELD path
WITH n, LAST(NODES(path)) as subgraphNode
REMOVE subgraphNode:Unprocessed
// find attach point node in each subgraph with smallest id
WITH n, min(id(subgraphNode)) as attachId
WITH DISTINCT attachId
MATCH (attachNode)
WHERE id(attachNode) = attachId
CREATE (attachNode)<-[:SUBGRAPH]-(:Subgraph)
RETURN count(*)
",{limit:100})

这是一次性查询,还是您打算定期查询?如果这是一个经常运行的查询,您的图多久更新一次,子图是否有可能与其他子图合并,或者被划分为更小的子图?这只是一个一次性查询。我已经运行了一个多小时了。你应该终止这个查询。它甚至都不会退回你想要的东西。查询返回的是图形中存在的最长路径,而不是最大子图形的大小。谢谢。如何找到它?使用APOC的路径扩展器添加了改进的查询,以更快地找到子图中的节点。
MATCH (sub:Subgraph)-[*]-(subgraphNode)
WITH sub, COUNT(DISTINCT subgraphNode) as subSize
RETURN MAX(subSize)
CALL apoc.periodic.commit("
// only process a batch of :Unproccessed nodes at a time
MATCH (n:Unprocessed)
WITH n LIMIT {limit}
// subgraphNode will be all nodes in the subgraph including n
CALL apoc.path.expandConfig(n,{bfs:true, uniqueness:"NODE_GLOBAL"}) 
  YIELD path
WITH n, LAST(NODES(path)) as subgraphNode
REMOVE subgraphNode:Unprocessed
// find attach point node in each subgraph with smallest id
WITH n, min(id(subgraphNode)) as attachId
WITH DISTINCT attachId
MATCH (attachNode)
WHERE id(attachNode) = attachId
CREATE (attachNode)<-[:SUBGRAPH]-(:Subgraph)
RETURN count(*)
",{limit:100})
MATCH (sub:Subgraph)
CALL apoc.path.expandConfig(sub,{minLevel:1, bfs:true, uniqueness:"NODE_GLOBAL"}) 
  YIELD path
WITH sub, LAST(NODES(path)) as subgraphNode
WITH sub, COUNT(DISTINCT subgraphNode) as subSize
RETURN MAX(subSize)