Nils
Nils

Reputation: 788

How to match multiple relationships to different nodes?

What I am trying to get to

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.

What I have tried

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.

What now?

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

Answers (1)

nimrod serok
nimrod serok

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

Related Questions