Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
02-25-2021 11:08 AM
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)
instead of :
(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,
02-27-2021 12:26 PM
did you try
match path = (a)-[:USES*]->(b)<-[:SWITCH]-(e)
return path order by length(path) limit 1
02-28-2021 08:55 AM
Thank you for your reply.
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.
02-28-2021 11:41 AM
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 ?
All the sessions of the conference are now available online