Migration to Neo4j 4.0 cause errors with Full Text Search + NOT EXISTS checks

I recently migrated from 3.5.x to 4.0.x and am experiencing one issue that I'm trying to understand how to proceed. I created a simplified query below to exemplify the issue that occurs with fulltext search and NOT EXISTS(property) queries:

CALL db.index.fulltext.queryNodes('MessageIndex', 'Test') YIELD node as m, score 
MATCH (u:User {id: "XXXXXX"})-[:likes]-(m)-[:from]-(o:Organization) 
WHERE EXISTS(m.messageType) AND (NOT EXISTS (m.expiryTime) OR m.expiryTime > 1594407732 ) 
RETURN DISTINCT m as message

Error:
NullCheckReferenceProperty(0,SlottedCachedPropertyWithPropertyToken(m,PropertyKeyName(expiryTime),0,false,55,2,NODE_TYPE,true)) (of class org.neo4j.cypher.internal.physicalplanning.ast.NullCheckReferenceProperty)

Version: Neo4j 4.0.6 Enterprise Server
Driver: Scala

Hello @kearnsw and welcome to the Neo4j community :slight_smile:

Did you get this error in the Neo4j Browser?

Is the request worked on 3.5?

Regards,
Cobra

Hi Cobra,

Thanks! This is through both the Scala/Java Driver and the Neo4j Desktop app. Yes, the queries ran on 3.5.

Can you try?

CALL db.index.fulltext.queryNodes('MessageIndex', 'Test') YIELD node as m, score 
MATCH (u:User {id: "XXXXXX"})-[:likes]-(m)-[:from]-(o:Organization)
RETURN DISTINCT m as message

Yes, I tried that. It works which is how I isolated the NOT EXIST(node.property) clause as the issue. However, this is still the recommended syntax for checking if a property does not exist according to the 4.0.x documentation.

Does this work?

CALL db.index.fulltext.queryNodes('MessageIndex', 'Test') YIELD node as m, score 
MATCH (u:User {id: "XXXXXX"})-[:likes]-(m)-[:from]-(o:Organization) 
WHERE EXISTS(m.messageType) 
RETURN DISTINCT m as message

Yes, and so does:

CALL db.index.fulltext.queryNodes('MessageIndex', 'Test') YIELD node as m, score 
MATCH (u:User {id: "XXXXXX"})-[:likes]-(m)-[:from]-(o:Organization) 
WHERE EXISTS(m.messageType) AND m.expiryTime > 1594407732
RETURN DISTINCT m as message

I’ve reproduced the same in other queries that only by removing the NOT EXISTS (node.property) clause does the issue resolve.

Try:

CALL db.index.fulltext.queryNodes('MessageIndex', 'Test') YIELD node as m, score 
MATCH (u:User {id: "XXXXXX"})-[:likes]-(m)-[:from]-(o:Organization) 
WHERE EXISTS(m.messageType) AND (m.expiryTime IS NULL OR m.expiryTime > 1594407732 ) 
RETURN DISTINCT m as message

That worked, thank you! Is there a functional difference between node.property IS NULL and NOT EXISTS(node.property)? I'm just wondering why the docs recommend the latter.

1 Like

To my knowledge, there is no difference, it is just a different syntax. I'm still surprised your syntax didn't work :slight_smile: