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.

Path that return a unique node and no relationship

madiskou
Graph Buddy

Hello,
I have this cypher query:

MATCH p=(no {name:'nodeName'})<-[:enfant*0..]-(parent:application) 
unwind nodes(p) as n unwind relationships(p) as r
with collect( distinct {id: id(n), name: n.name, labels: labels(n)}) as nl,
collect( distinct {source: id(startnode(r)), target: id(endnode(r))}) as rl 
RETURN {nodes: nl, links: rl}

This request retrun the path between a node and all his parents and then transform into d3js format(nodes&links).
i have these cases :
1- the start node is not an application --> the path return all nodes and relations so the request is good
2 - the start node is already an application, so the path return this node and then i have this response:

{"nodes":[],"links":[]}

and normally I will have :

{"nodes":[{id: 111, name: 'nodeName', labels:['application']}],"links":[]}

Any help or explication please ?

Thank you.

1 ACCEPTED SOLUTION

You can do that, but you can't supply the empty list in the UNWIND itself (since the UNWIND of the empty list is what wipes out your rows in the first place).

Wait until after the aggregation of the relationships, then use a list comprehension to transform the value of each relationship in the list. For an empty list, nothing will be transformed and you'll keep the empty list as is.

...
with collect( distinct {id: id(n), name: n.name, labels: labels(n)}) as nl,
collect(DISTINCT r) as rels
WITH nl, [r IN rels | {source: id(startnode(r)), target: id(endnode(r))}] as rl
RETURN {nodes: nl, links: rl}

View solution in original post

4 REPLIES 4

madiskou
Graph Buddy

When i test without relationships like this :

MATCH p=(no {name:'nodeName'})<-[:enfant*0..]-(parent:application) 
WITH p
unwind nodes(p) as n 
with collect( distinct {id: id(n), name: n.name, labels: labels(n)}) as nl
RETURN {nodes: nl}

i have a reponse :

{"nodes":[{"name":"nodeName","id":111,"labels":["application"]}]}    

so the problem is in the collect() with relationships because its empty, i don't know how can i fix that ?

When you UNWIND an empty list, it wipes out the rows (it's like doing a cartesian product against each element of the list, and a multiply by 0 elements means the row is gone).

You can circumvent this with a CASE that will supply a single element list in place of an empty list, allowing you to keep 1 row and not wiping out any data.

...
unwind nodes(p) as n 
unwind CASE WHEN length(p) = 0 THEN [null] ELSE relationships(p) END as r
...

Thank you @andrew.bowman now i understand better, can i return an empty array (list) instead of null because what i want in the end is a response like :

{"nodes":[{id: 111, name: 'nodeName', labels:['application']}],"links":[]}

not this :

{"nodes":[{id: 111, name: 'nodeName', labels:['application']}],"links":[{source: null, target: null}]}

You can do that, but you can't supply the empty list in the UNWIND itself (since the UNWIND of the empty list is what wipes out your rows in the first place).

Wait until after the aggregation of the relationships, then use a list comprehension to transform the value of each relationship in the list. For an empty list, nothing will be transformed and you'll keep the empty list as is.

...
with collect( distinct {id: id(n), name: n.name, labels: labels(n)}) as nl,
collect(DISTINCT r) as rels
WITH nl, [r IN rels | {source: id(startnode(r)), target: id(endnode(r))}] as rl
RETURN {nodes: nl, links: rl}