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.

Map function OR returns boolean instead of properties

Hi all,

I am trying to map the results of my match when there are 2 different searches into 1.
I added my code below

UNWIND $data AS row
OPTIONAL MATCH (a:NodeA)
WHERE a.id = row.id
OPTIONAL MATCH (a)-[:REL_2]->(c1:NodeC)
WITH a, collect(c1) AS lista
OPTIONAL MATCH (a)-[:REL_1]-(:NodeB)-[:REL_2]->(c2:NodeC)
WITH a, lista, collect(c2) AS listb
RETURN a{.*, List: lista OR listb} AS search

However this returns a boolean which is not the return I want. What I want is the properties of nodeC for each NodeA, since NodeA can only either have one the relationships and not both. Thus the result for example would be like:

{a_properties: 'value', List: [{ key: value }] }
Whereby if lista is empty display listb or if listb is empty display lista

Thanks in advance

1 ACCEPTED SOLUTION

I think a CASE WHEN x THEN y ELSE z END could solve your problem. Can you try this:

WITH a, (CASE WHEN size(lista) == 0 THEN listb ELSE lista END) as list
RETURN a{.*, List: list} 

View solution in original post

5 REPLIES 5

I think a CASE WHEN x THEN y ELSE z END could solve your problem. Can you try this:

WITH a, (CASE WHEN size(lista) == 0 THEN listb ELSE lista END) as list
RETURN a{.*, List: list} 

Thank you, this worked for me

mdfrenchman
Graph Voyager

@tarendran.vivekanand, OR is a boolean operator in cypher will always give you a boolean.

CASE statement as @sunny.pelletier outlined would be a good way to solve that.

Thanks for the info @mdfrenchman, I did not know that

We can actually simplify this by use of optional connections:

UNWIND $data AS row
OPTIONAL MATCH (a:NodeA)
WHERE a.id = row.id
OPTIONAL MATCH (a)-[:REL_1*0..1]->()-[:REL_2]->(c:NodeC)
WITH a, collect(c) AS List
RETURN a {.*, List} AS search

The *0..1 means that the relationship may or may not exist, so the node it points to (the one that is empty in the pattern) may actually be the same node as a, having not traversed any relationship, or it may have traversed a relationship. From either of those, we traverse :REL_2 to get to a :NodeC to fulfill the pattern, so we can use a single variable to address :NodeC nodes that are 1 or 2 hops away.

My approach here assumes that we don't need to check that a :NodeB exists between them, but if you DO need that restriction, then you can fix it with:

...
OPTIONAL MATCH path = (a)-[:REL_1*0..1]->()-[:REL_2]->(c:NodeC)
WHERE length(path) = 1 OR 'NodeB' IN labels(nodes(path)[1])
...

More about this technique here: