1
votes

I'm migrating to Neo4j 1.9 and updating the cypher queries according to the deprecations migration guide, specifically:

The ! property operator in Cypher Expressions like node.property! = "value" have been deprecated, please use has(node.property) AND node.property = "value" instead.

The problem is that when using the HAS clause in combination with NOT I can't get the expected result. For example:

When the status property exists and is set to something other than "DONE":

AND not(n.status! = "DONE") 

evaluates true (as expected)

AND not(has(n.status) AND n.status = "DONE")

evaluates false???

When the status property doesn't exist

AND not(n.status! = "DONE") 

evaluates false

AND not(has(n.status) AND n.status = "DONE")

throws exception because the node doesn't exist, surely HAS should have prevented this? It's as though wrapping the check in NOT prevents the HAS check from being executed.

This can be reproduced via the live query examples on the neo4j docs website using the following queries:

MATCH n 
WHERE NOT (n.name! = 'Peter') 
RETURN n

This returns all (3) nodes who either have no name or whose name is not "Peter". This is the result I want to reproduce but without using the now deprecated "!" operator.

MATCH n 
WHERE NOT (HAS (n.name) AND n.name = 'Peter') 
RETURN n

Throws a node not found exception because one node doesn't have a name property. :/

MATCH n 
WHERE (HAS (n.name) AND n.name = 'Peter') 
RETURN n

Correctly returns the node whose name is "Peter".

I've tried rewriting the query in a few alternative ways but can't seem to reliably get the result I want that matches the deprecated ! operator. Maybe it's just getting late and I'm missing something obvious? :)

Any Help is appreciated!

Thanks, Mark.

1

1 Answers

6
votes

I think the second query raising an exception is a bug.

What you can do is use de Morgan's law to transform the predicate:

MATCH n 
WHERE NOT (HAS (n.name)) OR (n.name <> 'Peter') 
RETURN n