Given the following bit of cypher (node cardinality, where node n has > 1 connected B labelled nodes):
MATCH (n)-[:HAS_B]->(:B)
WHERE SIZE( (n)-[:HAS_B]->(:B) ) > 1
How would I further filter for where the set of connected B nodes have the same value for a property on the B nodes connected to n?
i.e. I want to match IF AND ONLY IF for any n where ALL the B-labelled nodes connected to n have the identical value for a specific property, so it would make a match like so:
MATCH (n)-[:HAS_B]->(b:B)
WHERE SIZE( (n)-[:HAS_B]->(:B) ) > 1
with n, collect(distinct b.magic_property) as bagOfB
with n where size(bagOfB) = 1
return n
Hey Harold, that's on the right path to the solution I found.
To make it simple, let's assume our property is named x, and it is boolean. In this example, I only want to match where all b.x connected to a given n are TRUE:
MATCH (n)-[:HAS_B]->(b:B)
WHERE SIZE( (n)-[:HAS_B]->(:B) ) > 1
WITH DISTINCT n, COLLECT(b.x) AS xVals
// i.e. all B-labelled nodes connected to a given node 'n' have the property 'x' = TRUE
WHERE NOT FALSE IN xVals
RETURN n
Hi Gary, apart from replacing WHERE NOT FALSE IN xVals with WHERE all(x IN xVals WHERE x = TRUE) it would be of use? Because the replacement isn't easier to read, and can't see how it would be faster.
I agree...Your implementation was slick...These predicates allow for more capability than what you needed. Just wanted to highlight them for future use, and they could have been used to solve problems like yours. As you noted, you came up with a predicate specific to your problem that is easier to understand.