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.

Conditional execution logic with results from each branch

deepak
Node Clone

I am working on some conditional queries and looking for some guidance over recommended practices. Can this query be optimized further? I am using version 4.2.1.
EDIT: Please note, the query needs to return the result of each branch. In my case, auth object carries the results from each condition.

//1. Most code examples are using multiple match statements for building queries.
// Does this query pattern have any disadvantage over multiple match/where statement? 
MATCH (c1: Country{cId: "1"}) <-[r1:CITIZEN_OF] - (p:Person{pId:"A"})-[r2:CITIZEN_OF] -> (c2: Country{cId: "2"})

//2. This validation logic is common to multiple queries. Can this be reused somehow?
WITH c1, c2, r1, r2, p
	CASE 
	WHEN p.alive = false THEN {result: "p_not_alive", c1: null, c2: null, p: null}
	WHEN r1.passport = false THEN {result: "c1_passport_missing", c1: null, c2: null, p: null}
	WHEN r2.passport = false THEN {result: "c2_passport_missing", c1: null, c2: null, p: null}
	ELSE {result: "ok", c1: c1, c2: c2, p: p}
	END as auth  

//Business logic follows:	
//3. Is setting properties on null ok? I commonly see use of [] over null 
//4. Is it safe to use SET auth.c1.incoming = true over SET (CASE when auth.result = "ok" then auth.c1 end).incoming = true
SET auth.c1.incoming = true
SET auth.c2.outgoing = true
SET auth.p.travel = true
RETURN auth

I think there's a better way to do this using conditional procedure apoc.do.when() but I am not able to formulate that query. Additionally, triggering APOC procedures from Java seems like fighting cypher syntax - I don't know if it has any performance impact as well. I read posts where people avoid using APOCs for what can be done with regular cypher queries.

2 REPLIES 2

Benoit_d
Graph Buddy

Hi @deepak,

if you separate the query in one for setting and one for display, you will have more flexibility:

MATCH (c1: Country{cId: "1"}) <-[r1:CITIZEN_OF] - (p:Person{pId:"A"})-[r2:CITIZEN_OF] -> (c2: Country{cId:"2"})
Where p.alive = true and r1.passport <> false and r2.passport <> false 
SET c1.incoming = true
SET c2.outgoing = true
SET p.travel = true

should be all what you need in order to set correctly the 3 properties.

Sorry for the confusion @Benoit_d. I edited my post to reflect the requirement better. The query not only needs to execute conditionally, but also needs to return why it could not be executed successfully. In this scenario, we need to know if we could not modify the nodes because person was not alive, or had missing passport. If MATCH returns no results, my application logic assumes that the relation does not exist, so I did not use OPTIONAL MATCH.