I have 3 type of nodes: FOLDER, TYPE_A, TYPE_B and one relationship: CONTAINS;
I am having difficulty in writing cypher, in a single query, to fetch this:
if(folder CONTAINS TYPE_A) {
return ids of TYPE_A
} else if (folder CONTAINS TYPE_B) {
then return ids of TYPE_B
} else {
return empty array;
}
Can someone help?
One way is to use apoc.do.when
to fetch the ids
of TYPE_B
conditionally, when no TYPE_A
nodes are present. Like this:
MATCH (n:FOLDER)
OPTIONAL MATCH (n)-[:CONTAINS]-(m:TYPE_A)
WITH n, collect(id(m)) AS typeAIds
CALL apoc.do.when(
size(typeAIds) = 0,
'OPTIONAL MATCH (n)-[:CONTAINS]-(m:TYPE_B) WITH n, collect(id(m)) AS typeBIds RETURN typeBIds',
'RETURN [] as typeBIds',
{n: n}
)
YIELD value
RETURN n, typeAIds + value.typeBIds AS ids
In this query, we first fetch the TYPE_A
node ids and collect them in an array. If those ids
are not present, then we fetch TYPE_B
node ids, within apoc.do.when
. Finally, we return the output. This is a bit more optimized as we only fetch the relationships if needed. You will need to install, APOC
library for this query to work. Another variant of the same query is this:
MATCH (n:FOLDER)
CALL apoc.do.when(
SIZE([(n)-[:CONTAINS]-(:TYPE_A) | 1]) <> 0,
'OPTIONAL MATCH (n)-[:CONTAINS]-(m:TYPE_A) WITH n, collect(id(m)) AS typeAIds RETURN typeAIds',
'RETURN [] as typeAIds',
{n: n}
)
YIELD value AS v1
CALL apoc.do.when(
SIZE([(n)-[:CONTAINS]-(:TYPE_B) | 1]) <> 0 AND SIZE(v1.typeAIds) = 0,
'OPTIONAL MATCH (n)-[:CONTAINS]-(m:TYPE_B) WITH n, collect(id(m)) AS typeBIds RETURN typeBIds',
'RETURN [] as typeBIds',
{n: n}
)
YIELD value AS v2
RETURN n, v1.typeAIds + v2.typeBIds AS ids