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.

Creating Relationship Conditionally Returns Unexpected result

Hello,

I was working on community version and I switched to enterprise to test my cypher. I encountered a problem that does not occur on community version. 

I am trying to create a relation which is conditional according to nodes. 

bekirtaskin05_0-1671009627946.png

My cypher is;

MATCH (u:User {identity: "user1"})
CALL {
    WITH u
    OPTIONAL MATCH (f:User {identity: "user2", private: TRUE})
    MERGE (u)-[req:CONNECTION_REQUESTED]->(f)
    return req
}
CALL {
    WITH u
    OPTIONAL MATCH (f:User {identity: "user2", private:  FALSE})
    MERGE (u)-[con:CONNECTED]->(f)
    RETURN con
}
RETURN req, con
 
One of the relation will be created and other one should be null. However none of the relations is null.
bekirtaskin05_3-1671010166381.png

Can you help me to understand why non-created relation is not null? I am using 4.4.9-enterprise for testing. 

Thank you

2 REPLIES 2

I got the following message when I executed your query with dummy data: 

Screen Shot 2022-12-15 at 1.17.57 PM.png

After adding the configuration option, I got a relationship for 'con' as you did. Notice that the id (identity) is negative. As such, this is not a real relationship. I could not find it in my db after executing the query. Do you? 

Screen Shot 2022-12-15 at 12.55.04 PM.png

The issue with using call subqueries that return values as you are doing, is that if one does not return a value the result of the outer query will also not return a value. This is guaranteed in your case since the conditions of each are mutually exclusive. I refactored the query using apoc.do.when instead. See if this works for you.

match (u:User {identity: "user1"})
match (f:User {identity: "user2"})
call apoc.do.when(
f.private = true,
'
    with $f as f, $u as u
    merge (u)-[r:CONNECTION_REQUESTED]->(f)
    return r
',
'
    with $f as f, $u as u
    merge (u)-[r:CONNECTED]->(f)
    return r
',
{u:u, f:f}
) yield value
return u, f, value.r

The above solution is fairly general, as you can do anything differently in the two queries. If you just are creating a relationship between the two nodes with different types, then the following does this and is simpler. 

match (u:User {identity: "user1"})
match (f:User {identity: "user2"})
with u, f, case f.private when true then 'CONNECTION_REQUESTED' when false then 'CONNECTED' end as rel_type
CALL apoc.create.relationship(u, rel_type, {}, f) yield rel
return u, f, rel

 

Thank you for your time and solution. Using CREATE instead of MERGE also works. I was hoping a system parameter for quick fix :). I must review all cyphers and fix them one by one.