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.

Path from a null object

shan
Graph Buddy

Hi,

I am seeing some strange behaviour in neo4j when I deal with null objects. I wonder if anyone can help me understand and justify this behaviour?
Let's assume I set my parameter first using :params {b:null}. Then I run the following:

MERGE (a:Test {name:"a"})
WITH a
OPTIONAL MATCH (b:Test {name:$b})
WITH (b)-[*1..5]->(a) as res
RETURN res

This returns a null row. Now if you slightly change this query to the following

merge (a:Test {name:"a"})
WITH a
OPTIONAL MATCH (b:Test {name:$b})
WITH (b)-[*1..5]->(a) AND true as res
RETURN res

it returns true while I expect to get null given that (b)-[*1..5]->(a) was null (from the previous query) and, given that null AND true should be null according to https://neo4j.com/docs/cypher-manual/current/syntax/working-with-null/#cypher-null-logical-operators. Even if I use EXISTS, I get true:

merge (a:Test {name:"a"})
WITH a
OPTIONAL MATCH (b:Test {name:$b})
WITH EXISTS((b)-[:HAS_ATTR*1..8]->(a)) as res
RETURN res
3 REPLIES 3

intouch_vivek
Graph Steward

@shan,

MERGE (a:Test {name:"a"})
WITH a
OPTIONAL MATCH (b:Test {name:$b})
WITH (b)-[*1..5]->(a) as res
RETURN res

Returns a row with null value because of $b that is Null, and you are doing operation with that row but not with the row value. This is the reason in second query it is giving to true. Existence of row is also shown in the third query too.

Thanks @intouch.vivek.
I am afraid I don't follow. After the OPTIONAL MATCH, I have a row with two fileds, a and b where the value of b is null but a is not null. Now in WITH (b)-[*1..5]->(a) AND true as res, I am finding a path from b to a which is again null. I don't understand why null AND true evaluates to true.

When you are using Optional Match you are trying to execute Left outer join and your are fetching a row. The value of that row in Null. When you applying
WITH (b)-[*1..5]->(a) AND true as res
you are processing True and True that is True.

Instead if you run the same query without Optional it will give you no result.