Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return top n biggest cluster in Neo4j?

in my database, the graph looks somehow like this:

cluster

I want to find the top 3 biggest cluster in my data. A cluster is a collection of nodes connected to each other, the direction of the connection is not important. As can be seen from the picture, the expected result should have 3 clusters with size 3 2 2 respectively.

Here is what I came up with so far:

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

However, it has 2 problems:

  1. I think the query is wrong because the size() function does not return the number of nodes in a cluster as I want, but the number of sub-graph matching the pattern instead.
  2. The LIMIT clause limits the number of nodes to return, not taking the top result. That's why I put 100 there.

What should I do now? I'm stuck :( Thank you for your help.


UPDATE

Thanks to Bruno Peres' answer, I'm able to try algo.unionFind query in Neo4j Graph Algorithm. I can find the size of my connected components using this query:

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

And here is the result: Connected Components

But that's all I know. I cannot get any information about the nodes in each component to visualize them. The collect(nodeId) takes forever because the top 2 components are too large. And I know it doesn't make sense to visualize those large components, but how about the third one? 235 nodes are fine to render.

like image 551
Triet Doan Avatar asked Mar 06 '18 15:03

Triet Doan


People also ask

What is unwind in Neo4j?

With UNWIND , you can transform any list back into individual rows. These lists can be parameters that were passed in, previously collect -ed result or other list expressions. One common usage of unwind is to create distinct lists. Another is to create data from parameter lists that are provided to the query.

Why use a cluster for a Neo4j application Choose all that apply?

Causal consistency in Neo4j means that an application is guaranteed to be able to consistently read all data that it has written. Most Neo4j applications use clustering to ensure high-availability. The scalability of the Neo4j database is used by applications that utilize multiple data centers.

What is a causal cluster?

Causal Clustering is the next generation multi-site replication technology. It supports a distributed system clustering model for data centers. With Casual Clustering, you can experience better performance for remote team members and more robust replication, ensuring your teams are always up and running.


1 Answers

I think you are looking for Connected Componentes. The section about connected components of Neo4j Graph Algorithms User Guide says:

Connected Components or UnionFind basically finds sets of connected nodes where each node is reachable from any other node in the same set. In graph theory, a connected component of an undirected graph is a subgraph in which any two vertices are connected to each other by paths, and which is connected to no additional vertices in the graph.

If this is your case you can install Neo4j Graph Algorithms and use algo.unionFind. I reproduced your scenario with this sample data set:

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)

Then running 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

The result will be:

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

EDIT

From comments:

how can I get all nodeId of a specific setId? For example, from my screenshot above, how can I get all nodeId of the setId 17506? That setId has 235 nodes and I want to visualize them.

  1. Run call CALL algo.unionFind('', ':type', {write:true, partitionProperty:"partition"}) YIELD nodes RETURN *. This statement will create apartition` property for each node, containing the partition ID the node is part of.
  2. Run this statement to get the top 3 partitions: match (node) with node.partition as partition, count(node) as ct order by ct desc limit 3 return partition, ct.
  3. Now you can get all nodes of each top 3 partitions individually with match (node {partition : 17506}) return node, using the partition ID returned in the second query.
like image 117
Bruno Peres Avatar answered Oct 07 '22 13:10

Bruno Peres