0
votes

I am new to neo4j and cypher and trying to build the following query: Select the nodes and the relations from the picture that are circled by the brown color (A, B, C, D, E, F, G, H and the relations) as the requirement is in the tree-like structure if I encounder a blue node I should add this node to the result but omit its children (related nodes). Relation directions are not important in this case.

Can you help me?

diagram1

diagram2

EDIT: And a second example is added. Again the required result are the nodes encircled by the brown line.

2
do you want the E node in the final list if E was connected to FTheTeacher
yes, as E will be also connected to B.yanislavgalyov
so , different color nodes have different labels or the color is a node property ?TheTeacher
@yanislavgalyov so you want all indirectly connected Leaves and Systems, as well as Elements connected directly to elements from that search?Nobody
@Nobody I added a second diagram. The starting point is node A and the result are nodes that expand from A and end in every blue node that is encountered. The required result of nodes is encircled by the brown line.yanislavgalyov

2 Answers

1
votes
MATCH p=(c:LabelSystem)-[r*]->(d) 
WHERE d:LabelLeaf OR d:LabelElement 
WITH COLLECT(DISTINCT d) as labelElements,COLLECT(DISTINCT c) as labelSystem , c
MATCH (ls:LabelSystem)-[]-(le:LabelElement) 
WHERE le IN labelElements AND ls <> c
WITH COLLECT(DISTINCT ls) as  childLabelSystems,labelSystem,labelElements,c.uniqueProperty as uniqueIdentifier
WITH labelElements+childLabelSystems+labelSystem as allNodes,uniqueIdentifier
RETURN uniqueIdentifier,allNodes 

if you use color as property inside node, you can adjust WHERE accordingly

0
votes

After reading the apoc documentation I found apoc.path.expandConfig function that almost solved my problem. So the solution is:

  1. get paths to nodes that are Element or Leaf
  2. get paths to system nodes
  3. for path get relation return and return segment of the path as: (start)-[relationship]-(end)
  4. union those segments to remove duplicates

It is working and my next task is to test performance with large graphs. Any thoughts? @Nobody @TheCrusher

match (start: System) 
where id(start)=1
call apoc.path.expandConfig(start, { labelFilter: 'Element|Leaf' }) yield path
unwind relationships(path) as x
return startnode(x) as s, x as r, endnode(x) as e
union 
match (start: System) 
where id(start)=1
call apoc.path.expandConfig(start, { labelFilter: '>System' }) yield path
unwind relationships(path) as x
return startnode(x) as s, x as r, endnode(x) as e

EDIT: I came up with another query which does the work:

match (s: System)-[r*]-(m)
where id(s)=1 and (m:Element or m:Leaf or m:System) and not (s)-[*]-(:System)-[*]-(m)
unwind r as r1
with distinct r1 as rd
return startnode(rd), rd, endnode(rd)