Reputation:
I'm looking to perform a set operation in a Neo4j cypher. Basically I have relationships to a set of nodes from two directions, I want to find only nodes on one side which have a relationship to all those on the other.
Given a graph similar to the following:
/----- b1 -\
/ \
a ------ b2 --c1
\ \/
\ /\
\---- b3 --c2
I would only like c1
to be returned, as c2
does have a direct relationship with b1
while a
does.
Upvotes: 0
Views: 550
Reputation: 1462
You could possibly use a label to denote nodes as being in one set or the other (am assuming they're mutually exclusive). I'm also assuming that the node "a" is a root node and/or doesn't need to be directly connected to "c1" or "c2".
In your above ASCII art example, assuming "b1" has a label of "Set1" and all others have "Set2", something like this might work:
MATCH (n:Set2)--(o:Set1), (allS1:Set1)
WHERE length(collect(o)) = count(allS1)
WITH n, length(collect(o))
RETURN n
...or a variation thereof. Again, this is assuming that you're doing this one set at a time. Doing both shouldn't take too much more effort. It also may not be the most efficient, but it should do the trick. Give it a shot and let us know.
HTH, and as always, if there's a better way to do this (as there very well might be), let's see those answers!
Upvotes: 0
Reputation:
I have a solution which seems to work, but I don't know if it's optimal.
match (a:A)--(b:B)
with a, count(b) as bCount1
match (a)--(b:B)--(c:C)
with c, bCount1, count(b) AS bCount2
where bCount1 = bCount2
return c
Upvotes: 0