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.

Check if path exist or not

How can I check if a path exist or not. I have this query but not success

MATCH path = ((u:User)-[:HAS]->(s:Service)-[:PAID]->(c:Charged))
CALL apoc.case([length(path) = 0, "RETURN 'pending payment'"], "RETURN 'Already paid'") YIELD value
RETURN value

But if I do the same with collect, it works, how is that possible?

MATCH path = ((u:User)-[:HAS]->(s:Service)-[:PAID]->(c:Charged))
with collect(path) as hops
CALL apoc.case([hops = [], "RETURN 'pending payment'"], "RETURN 'Already paid'") YIELD value
RETURN value
1 ACCEPTED SOLUTION

MATCH (u:User)-[:HAS]->(s:Service)
WITH u, s
OPTIONAL MATCH p = (s)-[:PAID]->(c:Charged)
RETURN u, s, CASE WHEN length(p) = 0 THEN 'pending payment' ELSE 'Already paid' END

OR

MATCH (u:User)-[:HAS]->(s:Service)
RETURN u, s, CASE WHEN NOT exists((s)-[:PAID]->(:Charged)) THEN 'pending payment' ELSE 'Already paid' END

View solution in original post

9 REPLIES 9

Hello @undefined21

Which relationship do you want to check if it exists? (only PAID or HAS or both?)

Regards,
Cobra

Hi @Cobra. The relationship that I want to know if exist or not would be the PAID realtionship

Thanks for your time

MATCH (u:User)-[:HAS]->(s:Service)
WITH u, s
OPTIONAL MATCH p = (s)-[:PAID]->(c:Charged)
RETURN u, s, CASE WHEN length(p) = 0 THEN 'pending payment' ELSE 'Already paid' END

OR

MATCH (u:User)-[:HAS]->(s:Service)
RETURN u, s, CASE WHEN NOT exists((s)-[:PAID]->(:Charged)) THEN 'pending payment' ELSE 'Already paid' END

That was fast! I still need to get comfortable with cypher because there are lot syntax that I do not understand but thanks for your time! solved!

Hi again,

I am struggling to understand why using WHEN CASE syntax the following expression works

RETURN CASE WHEN length(p) = 0 THEN ...

but when we use the apoc function does not

CALL apoc.case([length(p) = 0, ...

I guess in both cases the output is a boolean but in the second case it throws NULL pointer exception. This is because we cannot use that kind of expression there or it is a wrong usage.

Thanks for your time!

Hi,

Difficult to say without seeing the full query but use OPTIONAL MATCH instead of MATCH.

The query would check if the service was paid or not, and the cypher would be the next one:

OPTIONAL MATCH p = (s)-[:PAID]->(c:Charged)
RETURN CASE WHEN length(p) = 0 THEN 'pending payment' ELSE 'Already paid' END

With that condition (length(p)=0), if there is not Charged node, it would jump to the else case because the length(p) is null and the condition wouldn't be true never if we equal 0. In that case, the possible options would be null OR 1. But what we want is that if we do not find the path, return pending payment. So using OPTIONAL MATCH, we should use IS NULL equality to check if path exist or not:

OPTIONAL MATCH p = (s)-[:PAID]->(c:Charged)
RETURN CASE WHEN length(p) IS NULL THEN 'pending payment' ELSE 'Already paid' END

The same with apoc.case function. Instead of equal 0, we can use as above IS NULL

OPTIONAL MATCH p = (s)-[:PAID]->(c:Charged)
CALL apoc.case([length(p) IS NULL, "RETURN 'pending payment'"], "RETURN 'Already paid'") YIELD value
RETURN value

So to recap, we have to use MATCH when we know the path exist and OPTIONAL MATCH when we do not have certainty of the existence

Thanks for your time!

What don't you use exists() function?

Is the solution not working?

There is nothing wrong. Actually is the function that I will use it but I was curious why it wasn't working the path approach. Also, I want it to have noted that case for the future, if I have the similar problem. No worries, you solved my problem, so thanks for your time!