I need to find shortest paths between nodes, but with some restrictions on relations types in good paths.
I have two relation types: A & B. Path is considered bad if it has two or more consecutive relation of type B:
Good path: ()-A->()-A->()<-A-()-B->()-A->()-B->()
Bad path: ()-A->()-A->()<-A-()-B->()<-B-()-A->()
The Cypher query:
MATCH path=allShortestPaths( (p:P{idp:123})-[rel:A|B*]-(p2:P{idp:124}) )
WHERE *some-predicate-on-path-or-rel*
RETURN path
is not a solution because the shortest good path may be longer than shortest bad paths.
Q1: Can this problem be solved by some Cypher query?
I can solve my problem with the embedded Java Neo4J API:
GraphDatabaseService graphDb = new GraphDatabaseFactory().newEmbeddedDatabase("db/store/dir/path");
TraversalDescription td = graphDb.traversalDescription()
.breadthFirst()
.evaluator(Evaluators.toDepth(max_depth))
.evaluator(Evaluators.endNodeIs(Evaluation.INCLUDE_AND_PRUNE, Evaluation.EXCLUDE_AND_CONTINUE, endNode))
.evaluator(new DoubleB_PruneEvaluator());
static class DoubleB_PruneEvaluator implements Evaluator {
@Override
public Evaluation evaluate(final Path path) {
Iterator<Relationship> lRels = path.reverseRelationships().iterator();
if (lRels.hasNext() && lRels.next().isType(MyRelTypes.B)) {
if (lRels.hasNext() && lRels.next().isType(MyRelTypes.B))
return Evaluation.EXCLUDE_AND_PRUNE;
}
return Evaluation.INCLUDE_AND_CONTINUE;
}
}
Q2: Is this solution is quite efficient? Or how to improve?
But my application is written on PHP and interacts with Neo4j server via REST protocol.
Q3: How can I run this solution by some REST query?