Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
07-30-2021 09:15 AM
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.
07-30-2021 11:59 AM
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.
07-30-2021 02:34 PM
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.
All the sessions of the conference are now available online