Reputation: 54
I have a graph with two different types of nodes A and B connected by a relationship rel. It exists such that there may be multiple nodes of A connected to one of B. My exact problem is this, suppose I have 2 nodes a1, a2 of type A connected to b1 via the relationship rel. I have node a3 of type A related to node b2. I want to find a node b3 which contains a1, a2 and a3 and then form a relationship between b3 and b2, b1 if they fulfill a property(b3.prop/b2.prop>x & b3.prop/b1.prop>x). Is it possible to write a query in cypher that handles multiple relationships like this?
Upvotes: 0
Views: 212
Reputation: 67044
This may work for your scenario:
MATCH (b1:B), (b2:B)
WHERE b1.id = 123 AND b2.id = 456
MATCH (a1:A)-[:rel]->(b1)
MATCH (a1)-[:rel]->(y1:B)
WHERE y1 <> b1 AND y1 <> b2
WITH b2, COLLECT(DISTINCT a1) AS a1s, COLLECT(DISTINCT y1) AS otherBs
WITH b2, [b IN otherBs WHERE ALL(a IN a1s WHERE (a)-[:rel]->(b))] AS candidates
WHERE SIZE(candidates) > 0
MATCH (a2:A)-[:rel]->(b2)
WITH candidates, COLLECT(a2) AS a2s
UNWIND [c IN candidates WHERE ALL(a IN a2s WHERE (a)-[:rel]->(c))] AS b3
RETURN b3
This query assumes the rel
relationship is directed from A
to B
, and it will only return a result if there are any appropriate b3
nodes. It first creates a list of all the possible B
candidates
related to the A
nodes related to b1
. Then it whittles down the candidates
list, keeping only the B
nodes that are also related to the A
nodes related to b2
.
There are many nuances in this query. For example, this snippet would abort the query if any A
node with a rel
relationship to b1
does not also have a rel
relationship to some other B
node (that is not the same as b1
and b2
):
MATCH (a1)-[:rel]->(b1)
MATCH (a1)-[:rel]->(y1:B)
WHERE y1 <> b1 AND y1 <> b2
Whereas the following refactoring of the above snippet would only abort the query if all A
nodes with a rel
relationship to b1
do not also have a rel
relationship to some other B
node (that is not the same as b1
and b2
):
MATCH (y1:B)<-[:rel]-(a1)-[:rel]->(b1)
WHERE y1 <> b1 AND y1 <> b2
Upvotes: 1