Sorry, to ask this question for the 100th time, but none of the previous posts was similar to my problem: I just want to get back TRUE or FALSE if a node with a certain label and a certain value of a property exists.
(u:User {user_id: 1} => TRUE / FALSE
All other posts where about MERGE and so on, but I don't want to create anything, I want to use it as a condition in an apoc.do.when-function.
This is tricky! the exists() function doesn't work the way I had hoped... and you can't compare the MATCH results with null.
but this works:
MATCH (u:User {user_id: 1})
WITH count(*) as count
CALL apoc.when (count > 0, // won't work so well if user_id isn't unique...
"RETURN true AS bool", // one or more users with user_id = 1
"RETURN false AS bool", // no users with user_id = 1
{count:count}
) YIELD value
return value.bool
There may be a better way to do this, but I don't know..
Remember apoc.do.when is for when you want to change the DB, apoc.when is if you are just reading.
[added] a better solution is further towards the end of this thread!
Thanks a lot, I have tried it with exists() and comparing with NULL - and as you said without any success. I did not come to the conclusion to try it with count().
I basically don't understand why Cypher (or at least APOC) does not provide a function for that.
@clem , please, visit the CASE statement documentation -> Expressions - Cypher Manual. It can be simply changed to condition. CASE statements exists from RDBMS too.
Good Morning,
thank you, but no, this is basically not exactly what I was looking for, because it gives me all users with all their email-addresses with a additional column true/false.
Of course you could filter it again, but this is a very expensive query.
I just want to know, if a node with a certain value of a property exists.
Wow, at the beginning I was pfff that's super easy...hoo no that's not indeed.
Funny, I like challenge, I didn't solve it yet but I see a OPTIONAL MATCH clause as an work around solution.
And by the way, null laws of neo4j implies that null is not equal to null since null is nothing not a value and then since we don't know what it is you can't compare something you don't know with something you don't know.
OPTIONAL MATCH (n:User{user_id:1})
RETURN n IS NOT NULL AS Predicate
The above solution is not appropriate if the OPTIONAL MATCH can find multiple (N) matches. That is because in that case it would: (1) do the work to find all N matches and not stop after finding just the first one, and (2) it would return N Predicate values (all true).
Here is one simple way to fix both issues:
OPTIONAL MATCH (n:User{user_id:1})
WITH n LIMIT 1
RETURN n IS NOT NULL AS Predicate
There are other solutions as well, including using the EXISTS() function properly.
The EXISTS function must be passed a pattern that has a relationship. Here is a tricky way to use a 0-length variable relationship pattern with EXISTS to match a node (that does not need to have a relationship). It is, unfortunately, hard to read; but it does work.
RETURN EXISTS((:User{user_id:1})-[*0]-()) AS Predicate
Also, neo4j 5.3 added the EXISTS subquery, which is a little easier to read: