I'm trying to check if a condition is met to return the desired node and if not met to not return anything. But in my case when the condition is not met a "null" node is returned (probably as expected).
I'm trying to see if a (user1) has "protected = false", then return the node, or else if "protected = true AND user2 [: FOLLOWS] user1" then return the node, other than that I don't want to return anything.
My cypher query is like this.
MATCH (u: User)-[r:CREATED]->(p:Post), (u2: User)
CALL apoc.case([
u.protected = false, 'RETURN p',
u.protected = true AND EXISTS((u2)-[:FOLLOWS]->(u)), 'RETURN p'
],
'',
{p:p, u:u, u2:u2}) YIELD value
RETURN value.p
When a user has "protected = true" and is not followed by user2 then it returns a NULL node. As I said before the returned NULL node might be the expected behavior but I'm asking- Is there a way to tweak this query, even more, to make it not return a NULL node when the condition is not met? OR is this a limitation of this specific procedure? Also is there a different way to implement this query? apoc.when also is not suited for this case. Is there a different way?
Thank you.
Try this:
MATCH (u: User)-[r:CREATED]->(p:Post)
OPTIONAL MATCH (u2:User)-[:FOLLOWS]->(u)
WHERE id(u2) <> id(u)
WITH COALESCE(u2) as u21, u, p
CALL
{
WITH u21, u, p
WITH u21, u, p where u.protected = false
RETURN p
}
CALL
{
WITH u21, u, p
WITH u21, u, p where u.protected = true and u21 is not null
RETURN p
}
return p
Try this:
MATCH (u: User)-[r:CREATED]->(p:Post)
OPTIONAL MATCH (u2:User)-[:FOLLOWS]->(u)
WHERE id(u2) <> id(u)
WITH COALESCE(u2) as u21, u, p
CALL apoc.case([
u.protected = false, 'RETURN p',
u.protected = true AND u21 is not null, 'RETURN p'
],
'',
{p:p, u:u, u2:u2}) YIELD value
RETURN value.p
I am not sure I fully understand the requirements, but I came up with this. The query finds all users that have a relationship to a Post. It then returns the post or the string 'no result' if neither of the conditions is satisfied.
MATCH (u:User)-[:CREATED]->(p:Post)
RETURN
CASE
WHEN u.protected = false THEN p
WHEN u.protected = true and EXISTS((:User)-[:FOLLOWS]->(u)) THEN p
ELSE 'no result'
END as result
Your query also works.. but the issue here is that if the condition is not met it will return the "no result", which it does in my case. But what I'm looking for is that it doesn't return the "no result" string, I don't want it to return anything if the condition is not met, only when the condition is met do I want to return the node.
So if a list of 10 nodes has one node which doesn't meet the condition then return the list with 9 nodes only and the "no result" one not to be returned. So the list in this case will be clean of any unwanted data.
SIMPLE AND EFFECTIVE. Your approach worked like a charm.
Thank you so much @glilienfield for taking the time to respond, your help is much appreciated.
Best regards.