I have a data model that's something like:
(PersonA)-[:KNOWS]->(PersonB)
(PersonA)-[:KNOWS]->(PersonC)
(PersonA)-[:IS_FRIENDS_WITH]->(PersonD)
(PersonA)-[:LIKES]->(PersonE)
I'd like to write a query to return PersonA, with lists of related person grouped by the relation type. i.e.
{
"id": "PersonA",
"knows": [
{"id": "PersonB"},
{"id": "PersonC"}
],
"is_friends_with": [
{"id": "PersonD"}
],
"likes": [
{"id": "PersonE"}
]
}
Importantly, I can't hard code the relation types — they could, in theory, be anything!
Any idea? I've tried using something like apoc.map.groupMulti
, but this only allows grouping on node properties, not the relationship type.
This should work:
MATCH (a:Person)-[r]->(b)
WHERE a.id = "PersonA"
WITH a, TYPE(r) AS t, COLLECT({id: b.id}) AS bIds
WITH a, COLLECT({t: t, bIds: bIds}) AS data
RETURN REDUCE(s = {id: a.id}, d IN data | apoc.map.setEntry(s, d.t, d.bIds))
The query assumes all person nodes have the Person
label and a unique id
property. The result looks likes this:
{
"id": "PersonA",
"IS_FRIENDS_WITH": [
{
"id": "PersonD"
}
],
"KNOWS": [
{
"id": "PersonB"
},
{
"id": "PersonC"
}
],
"LIKES": [
{
"id": "PersonE"
}
]
}