# Best path algorithm with relationship preference

Hello !

I'd like to know if there is a way to find a "best path" with only a starting node and relationships preferences.

For exemple, if we have this initial cypher :

CREATE (a {title: 'a'})-[:USES]->(b {title: 'b'})-[:USES]->(c {title: 'c'})<-[:SWITCH]-(d {title: 'd'})<-[:USES]-(e {title: 'e'})-[:SWITCH]->(b) RETURN *

I'd like, starting from a node, find any length path of USES relationships, but stop at first SWITCH incoming relationship.

With this example, starting from node a, I'd like to find as result :

(a)-[:USES]->(b)<-[:SWITCH]-(e)

(a)-[:USES]->(b)-[:USES]->(c)
(a)-[:USES]->(b)-[:USES]->(c)<-[:SWITCH]-(d)

Is there any existing algorithm allowing relationship preference ? I didn't find any. I looked at shortestPath, A* and Minimum Spanning Tree (Path Finding Algorithms - Developer Guides) but they don't exactly fit my need.
I would even prefer a standard cypher syntax instead of calling a function, but I couldn't find any.

Any help will be appreciated !

Thanks,

did you try

``````match path = (a)-[:USES*]->(b)<-[:SWITCH]-(e)
return path order by length(path) limit 1
``````

The fact, which I didn't mention, is that there could be no SWITCH relactionship (and no USES also). With your suggest, I could enhance one of my last attempt which was :

``````MATCH (a)
OPTIONAL MATCH p=(a)-[:USES*]->(b)
OPTIONAL MATCH (s)-[:SWITCH]->(b)
RETURN a,p,s
``````

to obtain :

``````MATCH (a)
OPTIONAL MATCH p=(a)-[:USES*]->(b)
OPTIONAL MATCH (s)-[:SWITCH]->(b)
RETURN a,p,s
ORDER BY length(p) LIMIT 1
``````

The point is on the ORDER BY and LIMIT clauses as you suggested.
It doesn't work as expected because p doesn't stop at first SWITCH relationship since this one is MATCH as optional.

This one may have the expected behavior :

``````MATCH (a)
OPTIONAL MATCH p=(a)-[:USES*]->(b)<-[:SWITCH]-(s)

CALL apoc.when(p IS NOT NULL, 'RETURN p', 'MATCH p=(a)-[:USES*]->(b) RETURN p', {p: p, a: a})
YIELD value

RETURN a, value.p, s
ORDER BY length(p)
LIMIT 1;
``````

But it needs apoc and I have to duplicate any WHERE condition in both the first OPTIONAL MATCH and the elseQuery. (not shown in this exemple)

Is there any sexier query to achieve this ?