1
votes

First time asking on SO and a newby of cypher and neo4j.

I need to get all the nodes, and all their relationships, that compose the lineage of a particular node; to display them in a directed graph I need a list of nodes and a list of the relationships (links). This is my dummy set of nodes, and this is what I want to get (nodes plus links): result

This is what I came up after hours of research and attempts:

MATCH lineage = (n:Sample {name:"P"})-[:CHILD_OF*]->(parent:Sample)
MATCH (parent)-[r_out]->(child)-[r_in]->(parent)
WHERE parent IN nodes(lineage) OR child IN nodes(lineage) 
RETURN
collect(DISTINCT parent) AS nodes,
collect({ source: parent.name, rel: type(r_out), target: child.name }) AS links_out,
collect({ source: child.name, rel: type(r_in), target: parent.name }) AS links_in;

(I created two different list of relationships so i can distinguish the source and target.)

However this does not return n in the list of nodes and actually multiplicates the links, as I guess returns all the possible paths between n and all the other nodes.

I could not figure out a solution and I am also convinced it should be a much more elegant query...

Any help? Thanks

2

2 Answers

3
votes

This is what I was looking for!

MATCH lineage = (child:Sample {name:"P"})-[:CHILD_OF*]->(parent:Sample)
MATCH (n:Sample)-[r_out]->(m:Sample)-[r_in]->(n:Sample)
   WHERE n IN nodes(lineage) AND m IN nodes(lineage)
RETURN
   child + collect(DISTINCT parent) AS nodes,
   collect(DISTINCT {source: n.name, rel: type(r_out), target: m.name}) +
   collect(DISTINCT {source: m.name, rel: type(r_in), target: n.name}) AS links

The plus sign merges the results in a single array, and so now I have in a single query my two arrays of nodes and links! :)

0
votes

i THINK i get your question and in case i do ... (otherwise my apologies )

Getting the nodes and getting the unique relations between all the nodes that came back is a two step process. you can see my answer here

Basically the first request gets you the nodes and then you query for all relationships where either side of the relationship is a node with one of the node ids you got back in the first query

match a-[r]-b where id(a) in [1,2...] and id(b) in [1,2,3...] return r

note that the array of integers is the same unique list of node ids from the first query.