cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Find matching set of parent-child nodes where all children have identical property value

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:

3X_4_0_4028765c63da3ff10e11a7731ebc42c2b978ecd2.png

Neo4j Version: 4.0.8

1 ACCEPTED SOLUTION

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

View solution in original post

6 REPLIES 6

Hi @benjamin.rood !

Can you try something like

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

?

Bennu

Oh, y’all wanted a twist, ey?

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

You should review the list predicate functions for future use. they are very helpful and would have been applicable in this case.

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.

Ah, okay, thanks Gary!