cancel
Showing results for 
Search instead for 
Did you mean: 

Join the community at Nodes 2022, our free virtual event on November 16 - 17.

Validating Shortest-Path status inside another Path

nima
Node Link

Problem

MERGE (Z1:Z {z_id : 'z1'})-[:HAS_CHILD]->(z2:Z {z_id : 'z2'})-[:HAS_CHILD]->(z3:Z {z_id : 'z3'})-[:HAS_CHILD]->(z4:Z {z_id : 'z4'})-[:HAS_CHILD]->(z5:Z {z_id : 'z5'})

Create (x1:X {x_id: 'x1'})-[:HAS_OBJ]->(y1: Y {y_id: 'y1'})-[:HAS_OBJ]->(x2:X {x_id: 'x2'})-[:HAS_OBJ]->(y2: Y {y_id: 'y2'})-[:HAS_OBJ]->(x3:X {x_id: 'x3'});

MATCH (y:Y {y_id: 'y1'}),(z:Z {z_id: 'z2'})  WITH y,z CREATE (y)-[:HAS_Z {status: true}]->(z);
MATCH (y:Y {y_id: 'y2'}),(z:Z {z_id: 'z2'})  WITH y,z CREATE (y)-[:HAS_Z {status: true}]->(z);
MATCH (y:Y {y_id: 'y2'}),(z:Z {z_id: 'z4'})  WITH y,z CREATE (y)-[:HAS_Z {status: false}]->(z);

  • Given: starNode (of type X), endNode (of type X) and z:Z node as input,
  • Find: All available paths between startNode to endNode
  • Condition: When all shortest-paths between all Y nodes (in the returned paths) to the given Z node are healthy (status=true)

Examples:

Say, in the example above & considering x1 as startNode & x2 s endNode ...

  • given Z: z1 there should be no path -> since there's no way to rearch z1 from any of Y Nodes
  • given Z: z3: there should be a valid path, since the shortest-paths available for all y nodes to Z nodes are in a healthy state (y1->z2-_z3 & y2->z2->z3)
  • given Z: v5: there should be no path -> Although the shortest path from y1 to z5 is in the healthy state (y1->z2->z3->z4->z5), but the shortest path from Y2 to z6 is not healthy (y2->z4->z5), since the status of y2->z4 is false

This was the first version of my Cypher query, but it's not working as expected (returns path in case of z: z5)

MATCH (z:Z) WHERE z.z_id = 'z5'
WITH z MATCH (start:X) WHERE start.x_id = 'x1'
with z,start MATCH (end:X) WHERE end.x_id = 'x3'
WITH z,start,end
MATCH p=(start)-[:HAS_OBJ*1..]->(y:Y)-[:HAS_OBJ*1..]->(end), p2=shortestPath((y)-[*1..]->(z))
WHERE ALL (
    r in relationships(p2) WHERE 
         type(r)= 'HAS_CHILD' OR (type(r) = 'HAS_Z' AND r.status = true)
)
return p

Thanks in advance

1 REPLY 1

nima
Node Link

I think I found the solution (by adding one extra line: WITH p,p2 between the last MATCH and WHERE clause) - letting the shortest-path function first find the existing shortest-path available (& not searching for a (shortest-)path which is compatible with predicate)

MATCH (z:Z) WHERE z.z_id = 'z5'
WITH z MATCH (start:X) WHERE start.x_id = 'x1'
with z,start MATCH (end:X) WHERE end.x_id = 'x3'
WITH z,start,end
MATCH p=(start)-[:HAS_OBJ*1..]->(y:Y)-[:HAS_OBJ*1..]->(end), p2=shortestPath((y)-[*1..]->(z))
WITH p,p2
WHERE ALL (
    r in relationships(p2) WHERE 
         type(r)= 'HAS_CHILD' OR (type(r) = 'HAS_Z' AND r.status = true)
)
return p,p2