如何返回Neo4j中最顶尖的群集?

时间:2018-03-06 15:42:53

标签: graph neo4j cypher graph-databases

在我的数据库中,图表看起来像这样:

cluster

我想在我的数据中找到前三大群集。集群是彼此连接的节点的集合,连接的方向并不重要。从图中可以看出,预期结果应该有3个簇,大小分别为3 2 2。

这是我到目前为止所提出的:

MATCH (n)
RETURN n, size((n)-[*]-()) AS cluster_size
ORDER BY cluster_size  DESC
LIMIT 100

然而,它有两个问题:

  1. 我认为查询错误是因为size()函数没有按照我的意愿返回集群中的节点数,而是返回与模式匹配的子图的数量。
  2. LIMIT子句限制要返回的节点数,而不是取得最高结果。这就是为什么我把100放在那里。
  3. 我现在该怎么办?我被困住了:(谢谢你的帮助。

    更新

    感谢Bruno Peres'回答,我可以在Neo4j Graph Algorithm中尝试algo.unionFind查询。我可以使用此查询找到连接组件的大小:

    CALL algo.unionFind.stream()
    YIELD nodeId,setId
    RETURN setId,count(*) as size_of_component
    ORDER BY size_of_component DESC LIMIT 20;
    

    结果如下: Connected Components

    但这就是我所知道的。我无法获得有关每个组件中的节点的任何信息以使其可视化。 collect(nodeId)需要永远,因为前2个组件太大。我知道将这些大型组件可视化没有意义,但第三个组件怎么样呢?可以渲染235个节点。

1 个答案:

答案 0 :(得分:3)

我认为您正在寻找Connected Componentes。关于Neo4j图形算法用户指南的连通组件的部分说:

  

已连接的组件或UnionFind基本上找到连接的组   每个节点可从其中的任何其他节点到达的节点   设置即可。在图论中,无向图的连通分量是   一个子图,其中任意两个顶点相互连接   路径,并且连接到图中没有其他顶点。

如果是这种情况,您可以install Neo4j Graph Algorithms并使用algo.unionFind。我用这个样本数据集重现了你的场景:

create (x), (y),
(a), (b), (c),
(d), (e),
(f), (g),
(a)-[:type]->(b), (b)-[:type]->(c), (c)-[:type]->(a),
(d)-[:type]->(e),
(f)-[:type]->(g)

然后运行algo.unionFind

// call unionFind procedure
CALL algo.unionFind.stream('', ':type', {})
YIELD nodeId,setId
// groupBy setId, storing all node ids of the same set id into a list
WITH setId, collect(nodeId) as nodes
// order by the size of nodes list descending
ORDER BY size(nodes) DESC
LIMIT 3 // limiting to 3
RETURN setId, nodes

结果将是:

╒═══════╤══════════╕
│"setId"│"nodes"   │
╞═══════╪══════════╡
│2      │[11,12,13]│
├───────┼──────────┤
│5      │[14,15]   │
├───────┼──────────┤
│7      │[16,17]   │
└───────┴──────────┘

修改

来自评论:

  

如何获取特定setId的所有nodeId?例如,来自我的   上面的截图,如何获取setId 17506的所有nodeId?那   setId有235个节点,我想要将它们可视化。

  1. 为每个节点运行调用CALL algo.unionFind('', ':type', {write:true, partitionProperty:"partition"}) YIELD nodes RETURN *. This statement will create a partition`属性,其中包含节点所属的分区ID。
  2. 运行此语句以获取前3个分区:match (node) with node.partition as partition, count(node) as ct order by ct desc limit 3 return partition, ct
  3. 现在,您可以使用第二个查询中返回的分区ID,使用match (node {partition : 17506}) return node分别获取每个前3个分区的所有节点。