Reputation: 788
I am trying to get nodes of outgoing relationships in separate columns. The resulting data should look like the following:
node1 | nodeRel1 | nodeRel2 |
---|---|---|
{...} | [{...}, {...}, ...] | [{...}, {...}, ...] |
{...} | [{...}, {...}, ...] | [{...}, {...}, ...] |
Where node1
is the starting node with label Label1
, nodeRel1
are all the nodes connected to node1
through REL1
with label Label2
, and nodeRel2
are all the nodes connected to node1
through REL2
with label Label3
.
EDIT:
To specify, this is quite doable with two relationships like so (as pointed out by @nimrod serok): MATCH ()-[]-(origin)-[]-()
, but this only works with two relationships. This needs to be extended to three, five, an arbitrary amount.
The first thing I tried was:
MATCH (node1:Label1)-[:REL1|:REL2]->(node2)
RETURN node1, collect(node2)
Collecting node2
would combine the results of different labels in one list under one column, so that would not work.
This post explains why using multiple matches won't work. (TLDR: it turns into an AND
condition, as opposed to the OR
type I am looking for.
Writing two separate queries and using UNION
to combine them would not work, as unions need the RETURN
structures to be the same, as per the docs. In my case, the first query would look like RETURN node1, collect(nodeRel1)
, and the second like RETURN node1, collect(nodeRel2)
, which are of different types.
I figured I would be able to achieve this by using RETURN
as follows:
RETURN node1, collect(nodeRel1), collect(nodeRel2)
Now, however, I am quite lost when it comes to writing the MATCH
clause. What query would give me the desired data? And, equally important, why?
Thanks in advance, Nils
Upvotes: 0
Views: 2431
Reputation: 16033
There are several options here, one of them is:
MATCH
the origin node and then OPTIONAL MATCH
which relationship type you need (since it is not mandatory that it will exist). The last part is to collect
each type's nodes
MATCH (n:Person)
WITH n
OPTIONAL MATCH (n)-[:LIKES]-(m)
WITH n, m
OPTIONAL MATCH (n)-[:LOVES]-(t)
RETURN n, collect(distinct(m)) as likes, collect(distinct(t)) as loves
For this sample data:
MERGE (b:Person {name: "Bob" })
MERGE (c:Person {name: "Charles" })
MERGE (a:Person {name: "Anna" })
MERGE (d:Person {name: "Kira" })
MERGE (e:Person {name: "Dan" })
MERGE (f:Person {name: "El" })
MERGE (a)-[:LIKES]-(b)
MERGE (a)-[:LIKES]-(c)
MERGE (a)-[:LIKES]-(d)
MERGE (e)-[:LOVES]-(a)
MERGE (e)-[:LOVES]-(b)
MERGE (f)-[:LOVES]-(a)
MERGE (d)-[:LOVES]-(b)
MERGE (f)-[:LOVES]-(a)
It gave me this:
╒══════════════════╤════════════════════════════╤════════════════════════════╕
│"n" │"likes" │"loves" │
╞══════════════════╪════════════════════════════╪════════════════════════════╡
│{"name":"Dan"} │[] │[{"name":"Bob"},{"name":"Ann│
│ │ │a"}] │
├──────────────────┼────────────────────────────┼────────────────────────────┤
│{"name":"El"} │[] │[{"name":"Anna"}] │
├──────────────────┼────────────────────────────┼────────────────────────────┤
│{"name":"Bob"} │[{"name":"Anna"}] │[{"name":"Dan"},{"name":"Kir│
│ │ │a"}] │
├──────────────────┼────────────────────────────┼────────────────────────────┤
│{"name":"Charles"}│[{"name":"Anna"}] │[] │
├──────────────────┼────────────────────────────┼────────────────────────────┤
│{"name":"Anna"} │[{"name":"Charles"},{"name":│[{"name":"El"},{"name":"Dan"│
│ │"Kira"},{"name":"Bob"}] │}] │
├──────────────────┼────────────────────────────┼────────────────────────────┤
│{"name":"Kira"} │[{"name":"Anna"}] │[{"name":"Bob"}] │
└──────────────────┴────────────────────────────┴────────────────────────────┘
Upvotes: 1