Hello,
In chapter "3.7.5.2. Filter on patterns using NOT
" it is said, that using the not operator only "patterns" can be excluded from the match. I would like to also put constraints on the properties of the nodes to be excluded. So something like
MATCH (A)-[ * ]->(B:myType)
WHERE B.value = 'x' AND NOT ((A)-[ * ]->(C:myType) WHERE C.value = 'y')
RETURN A, B
So the nodes C of type myType do exists, but I would like to exclude those with a specific property.
MY first idea was to use this:
MATCH (A)-[ * ]->(B:myType), (A)-[ * ]->(C:myType)
WHERE B.value = 'x' AND NOT (C.value = 'y')
RETURN A, B
But this would merely match the same node for B and C (or possibly another one that has a value different than 'y') but it would not check on the definite non-existence of a possibly existing node C that has 'y' as value.
Greetings
Georg
Hi Georg,
here NOT is not enough to exclude relations between A and C, you need to use EXISTS as well.
If you want to exclude all those relation between A and B where A also have relation with C with a property (value='y'). You can try this.
MATCH (A)-->(B:myType)
WHERE B.value = 'x' AND NOT EXISTS ((A)-->(:myType{value:'y'}) )
RETURN A, B
I hope this helps :)
best
surya
2 Likes
That solution looks nice. How would the solution look like if the constraint on the non existing node involves the calls of operators or functions ? Is it allowed to use the property-specifying-syntax including operators, e.g.
MATCH (A)-->(B:myType)
WHERE B.value = 'x' AND NOT EXISTS ((A)-->(:myType{sqrt(value * value + 1) > 5}) )
RETURN A, B
If you will try your query you will see that it will give an error. You cannot check for property like this
sqrt(value * value + 1) > 5
this can be checked in the where statement but not with the key:value way inside a node definition.
I can see that you are trying to limit your relationship between node A, B, where node B should have a label :myType
and a property value=x
but not a property sqrt(value * value + 1) > 5
if the nodes B and C have the same label, then you do not need to check another relation
EXISTS ((A)-->(:myType{value:'y'}) )
rather you can just check the property in the where statement. you can just implement it like this
MATCH (A)-->(B:myType)
WHERE B.value = 'x' AND sqrt(B.value * B.value + 1) <= 5
RETURN A, B
Yes, I presumed, that I would have to filter it with a WHERE, but how can I include the constraint, which I have to put in the where in the restricted scope inside the NOT EXISTS ? When I put it in the property constraints inside the curly brackets, it would look like this:
MATCH (A)-->(B:myType)
WHERE B.value = 'x' AND NOT EXISTS ((A)-->(C:myType{ WHERE sqrt(C.value * C.value + 1) <= 5}))
RETURN A, B
Or is it allowed to put inside the NOT EXISTS sub-statement complete queries, like this:?
MATCH (A)-->(B:myType)
WHERE B.value = 'x' AND NOT EXISTS (MATCH (A)-->(C:myType) WHERE sqrt(C.value * C.value + 1) <= 5) RETURN C)
RETURN A, B