Shortest path between two port , but the same BOAT

Hi im looking for the shortest path between two port(cities) but this path have a condition (be always in the same boat) . The name of the boat is an attribute of the relationship with the cost(ie distance) .
MERGE (a:Loc {name:"Casablanca"})
MERGE (b:Loc {name:"Algesiras"})
MERGE (c:Loc {name:"Genoa"})
MERGE (d:Loc {name:"Alexandria"})
MERGE (e:Loc {name:"Haifa"})
MERGE (f:Loc {name:"Agadir"})
MERGE (g:Loc {name:"Tangier city"})
MERGE (a)-[:ROAD {cost:50,BOAT:"CD"}]->(b)
MERGE (a)-[:ROAD {cost:50,BOAT:"CD"}]->(c)
MERGE (a)-[:ROAD {cost:100,BOAT:"CD"}]->(d)
MERGE (b)-[:ROAD {cost:40,BOAT:"CD"}]->(d)
MERGE (c)-[:ROAD {cost:40,BOAT:"AF"}]->(d)
MERGE (c)-[:ROAD {cost:80,BOAT:"CD"}]->(e)
MERGE (d)-[:ROAD {cost:30,BOAT:"CD"}]->(e)
MERGE (d)-[:ROAD {cost:80,BOAT:"OP"}]->(f)
MERGE (e)-[:ROAD {cost:40,BOAT:"DG"}]->(f)
MERGE (f)-[:ROAD {cost:40,BOAT:"AF"}]->(g);
,
the request for the shortest path is :
MATCH (start:Loc{name:"Algesiras"}), (end:Loc{name:"Agadir"})
CALL algo.shortestPath.stream(start, end, "cost")
YIELD nodeId, cost
MATCH (other:Loc) WHERE id(other) = nodeId
RETURN other.name AS name, cost

But i need to specify to this request, that it was be always the same BOAT ; Please help

image

You'll need to modify your data model so that you have a relationship type for each boat -- instead of a generic ROAD relationship, you'd want a specific route for each boat type:

MERGE (a)-[:CD_ROAD {cost:50}]->(b)
MERGE (a)-[:CD_ROAD {cost:50}]->(c)
MERGE (a)-[:CD_ROAD {cost:100}]->(d)
MERGE (b)-[:CD_ROAD {cost:40}]->(d)
MERGE (c)-[:AF_ROAD {cost:40}]->(d)
MERGE (c)-[:CD_ROAD {cost:80}]->(e)
MERGE (d)-[:CD_ROAD {cost:30}]->(e)
MERGE (d)-[:OP_ROAD {cost:80}]->(f)
MERGE (e)-[:DG_ROAD {cost:40}]->(f)
MERGE (f)-[:AF_ROAD {cost:40}]->(g);

Once you have a boat-specific relationshup type, you can filter your algorithm calls based on that relationship.

For example, you can load the data into memory:

CALL algo.graph.load('my-graph','Loc','AF_ROAD | CD_ROAD | OP_ROAD | DG_ROAD', 
     {relationshipWeight:'cost'}

And execute your algorithm for each boat type:

MATCH (start:Loc{name:"Algesiras"}), (end:Loc{name:"Agadir"})
CALL algo.shortestPath.stream(start, end, {'my-graph', 'CD_ROAD')
YIELD nodeId, cost
MATCH (other:Loc) WHERE id(other) = nodeId
RETURN other.name AS name, cost

To run for each boat type, you could swap out the relationship specified in your query.

@tomaz.bratanic recently published a great blog post exploring how to do this type of analysis -- i would check that out to get started: Building a graph analytics pipeline in Neo4j to explore the transport system in Rome | by Tomaz Bratanic | Towards Data Science