0
votes

I'm trying to make a cypher query to make nodes list which is using "multi match" as follows:

MATCH (N1:Node)-[r1:write]->(P1:Node),
      (P1:Node)-[r2:access]->(P2:Node)<-[r3:create]-(P1)
      WHERE r1.Time <r3.Time and r1.ID = r2.ID and r3.Time < r2.Time
      return nodes(*)

I expect the output of the Cypher to be all nodes of the result, but Cypher doesn't support nodes(*).

I know that there is a way to resolve this like thisa;

MATCH G1=(N1:Node)-[r1:write]->(P1:Node),
      G2=(P1:Node)-[r2:access]->(P2:Node)<-[r3:create]-(P1)
      WHERE r1.Time <r3.Time and r1.ID = r2.ID and r3.Time < r2.Time
      return nodes(G1), nodes(G2)

But the match part could be changed frequently so I want to know the way to get nodes from multi-match without handling variable for every match.

Is it possible?

1

1 Answers

0
votes

Your specific example is easy to consolidate into a single path, as in:

MATCH p=(:Node)-[r1:write]->(p1:Node)-[r2:access]->(:Node)<-[r3:create]-(p1)
WHERE r1.Time < r3.Time < r2.Time AND r1.ID = r2.ID
RETURN NODES(p)

If you want the get distinct nodes, you can replace RETURN NODES(p) with UNWIND NODES(p) AS n RETURN DISTINCT n.

But, in general, you might be able to use the UNION clause to join the results of multiple disjoint statements, as in:

MATCH p=(:Node)-[r1:write]->(p1:Node)-[r2:access]->(:Node)<-[r3:create]-(p1)
WHERE r1.Time < r3.Time < r2.Time AND r1.ID = r2.ID
UNWIND NODES(p) AS n
RETURN n
UNION
MATCH p=(q0:Node)-[s1:create]->(q1:Node)-[s2:read]->(q0)
WHERE s2.Time > s1.Time AND s1.ID = s2.ID
UNWIND NODES(p) AS n
RETURN n

The UNION clause would combine the 2 results (after removing duplicates). UNION ALL can be used instead to keep all the duplicate results. The drawback of using UNION (ALL) is that variables cannot be shared between the sub-statements.