Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
01-12-2023 02:38 AM - edited 01-12-2023 02:45 AM
Hi everybody!
I have a graph with a few thousand nodes which form unrelated clusters. I'd like to get a list of lists with the nodes with a certain label forming each cluster, regardless of the relation type linking them.
Let's consider this simple example:
CREATE
(:Person {name: "Andrea"})-[:LOVES]->(:Person {name: "Bob"})-[:LIKES]->(:Food {name: "pizza"}),
(n:Person {name: "Mike"})<-[:KNOWS]-(:Person {name: "Paul"})-[:KNOWS]->(:Person {name: "Jen"})<-[:LOVES]-(n)
If I'd like to know which persons are somehow related, then I would get:
[
["Andrea", "Bob"],
["Mike", "Paul", "Jen"]
]
Could please help me building such a query? Thanks!
Solved! Go to Solution.
01-12-2023 03:39 AM
Thank you very much, that is exactly what I was looking for.
So I first projected a new graph:
CALL gds.graph.project(
'myGraph',
'Person',
'*'
)
Then I retrieved information about each cluster (aka component) in myGraph:
CALL gds.wcc.stream('myGraph')
YIELD nodeId, componentId
RETURN gds.util.asNode(nodeId).name AS name, componentId
ORDER BY componentId, name
╒════════╤═════════════╕
│"name" │"componentId"│
╞════════╪═════════════╡
│"Andrea"│0 │
├────────┼─────────────┤
│"Bob" │0 │
├────────┼─────────────┤
│"Jen" │2 │
├────────┼─────────────┤
│"Mike" │2 │
├────────┼─────────────┤
│"Paul" │2 │
└────────┴─────────────┘
Could you suggest how to group names inside a list of lists?
01-12-2023 07:02 AM
This groups the names by componentId. Do you want further grouping?
CALL gds.wcc.stream('myGraph')
YIELD nodeId, componentId
RETURN collect(gds.util.asNode(nodeId).name) AS names, componentId
ORDER BY componentId
01-12-2023 02:55 AM - edited 01-12-2023 02:56 AM
You might need to extract connected components, Check https://neo4j.com/docs/graph-data-science/current/algorithms/wcc/
01-12-2023 03:39 AM
Thank you very much, that is exactly what I was looking for.
So I first projected a new graph:
CALL gds.graph.project(
'myGraph',
'Person',
'*'
)
Then I retrieved information about each cluster (aka component) in myGraph:
CALL gds.wcc.stream('myGraph')
YIELD nodeId, componentId
RETURN gds.util.asNode(nodeId).name AS name, componentId
ORDER BY componentId, name
╒════════╤═════════════╕
│"name" │"componentId"│
╞════════╪═════════════╡
│"Andrea"│0 │
├────────┼─────────────┤
│"Bob" │0 │
├────────┼─────────────┤
│"Jen" │2 │
├────────┼─────────────┤
│"Mike" │2 │
├────────┼─────────────┤
│"Paul" │2 │
└────────┴─────────────┘
Could you suggest how to group names inside a list of lists?
01-12-2023 05:30 AM
Can you give an example about 'list of lists'. What kind of data is this?
01-12-2023 05:37 AM
in the example above, something like this:
[
["Andrea", "Bob"],
["Mike", "Paul", "Jen"]
]
a list of components where each component is represented by a list of node names.
01-12-2023 05:58 AM - edited 01-12-2023 05:58 AM
In neo4j there is no explicit grouping logic. Group by works with aggregate functions so I will use 'count'. I suppose something similar to this would work for you.
WITH [
["Andrea", "Bob", "Andrea"],
["Mike", "Paul", "Jen","Bob"]
] as myList UNWIND myList as subList UNWIND subList as name return name, count(name)
returns
"Andrea" 2
"Bob" 2
"Mike" 1
"Paul" 1
"Jen" 1
01-12-2023 07:02 AM
This groups the names by componentId. Do you want further grouping?
CALL gds.wcc.stream('myGraph')
YIELD nodeId, componentId
RETURN collect(gds.util.asNode(nodeId).name) AS names, componentId
ORDER BY componentId
01-12-2023 03:05 PM
what can i say? OUTSTANDING job, guys. never seen such a good support before, congratulations.
All the sessions of the conference are now available online