Graph refactoring

cypher

(Sarantis Pantazis) #1

For the purposes of refactoring, I would like to find similar paths in my graph. I have several nodes joined with relationships of type NEXT and the paths are differentiated by an extra property.
For example, rel.pathType = "pathA".

I would like to find paths such as:
(m)-[r1:NEXT {pathType:"pathA"}]->(n)-[r2:NEXT {pathType:"pathA"}]->(o)
and
(m)-[r1:NEXT {pathType:"pathB"}]->(n)-[r2:NEXT {pathType:"pathB"}]->(o)
to decide whether I would like to replace them with one path.

This is one of several failed attempts.

MATCH (m)-[r1:NEXT]->(n)-[r2:NEXT]->(o)
WITH m,n,o,r1,r2,COUNT(r1) AS r1_cnt,COUNT(r2) AS r2_cnt
WHERE (r1.Move_ID = r2.Move_ID)
RETURN m,n,o,r1,r2

This just returns more or less all relationships.
Any ideas about how I could solve this? Thank you.


(Andrew Bowman) #2

How about something like this?

MATCH (m)-[r1:NEXT]->(n)-[r2:NEXT]->(o)
WHERE (r1.Move_ID = r2.Move_ID)
RETURN m, n, o, collect({r1:r1, r2:r2}) as routes

This way you'll get a single row for the set of nodes, with the collection of relationship pairs connecting them, with each pair having the same MOVE_ID.


(Sarantis Pantazis) #3

Thank you very much Andrew, this is in the right direction.

Your query now gives me the paths for any three nodes. I can also specify the node names N,M,O to check if I have double paths/routes between them:

MATCH (m {name:"M"})-[r1:NEXT]->(n {name:"N"})-[r2:NEXT]->(o {name:"O"})
WHERE (r1.Move_ID = r2.Move_ID)
RETURN m, n, o, collect({r1:r1, r2:r2}) as routes

Any idea about how to loop through the nodes? My goal is to print something only when we find a double route (i.e. the number of routes > 2) for a specific node combination. Thanks again.


(Andrew Bowman) #4

Sure, we'll just use a WITH instead of a RETURN, then add a WHERE clause to only keep rows where the routes list size is > 1 then return.

MATCH (m {name:"M"})-[r1:NEXT]->(n {name:"N"})-[r2:NEXT]->(o {name:"O"}) 
WHERE (r1.Move_ID = r2.Move_ID) 
WITH m, n, o, collect({r1:r1, r2:r2}) as routes
WHERE size(routes) > 1
RETURN m, n, o, routes

(Sarantis Pantazis) #5

Thank you. This is exactly what I needed.