您的模型需要更加具备图形化特点。也就是说,我认为在停止节点之间与公交信息之间的关系中,您不应该有一个数组属性。相反,公交车本身应该是节点,并且存在一种关系来表示它们在哪些站停靠。请考虑以下示例数据:
CREATE (a:Stop {name:'A'}),
(b:Stop {name:'B'}),
(c:Stop {name:'C'}),
(d:Stop {name:'D'}),
(a)-[:NEXT {distance:1}]->(b),
(b)-[:NEXT {distance:2}]->(c),
(c)-[:NEXT {distance:3}]->(d),
(b1:Bus {id:1}),
(b2:Bus {id:2}),
(b3:Bus {id:3}),
(b1)-[:STOPS_AT]->(a),
(b1)-[:STOPS_AT]->(b),
(b2)-[:STOPS_AT]->(a),
(b2)-[:STOPS_AT]->(b),
(b2)-[:STOPS_AT]->(c),
(b3)-[:STOPS_AT]->(b),
(b3)-[:STOPS_AT]->(c),
(b3)-[:STOPS_AT]->(d);
现在的图像如下:
![model](https://istack.dev59.com/8OcYn.webp)
使用这个模型,可以轻松地找到最小换乘次数的行程,并返回所有必要的换乘信息(如果适用)。例如,从A到D的所有最短行程(以换乘次数为标准):
MATCH (a:Stop {name:'A'}), (d:Stop {name:'D'})
MATCH p = allShortestPaths((a)-[:STOPS_AT*]-(d))
RETURN EXTRACT(x IN NODES(p) | CASE WHEN x:Stop THEN 'Stop ' + x.name
WHEN x:Bus THEN 'Bus ' + x.id
ELSE '' END) AS itinerary
找到了三条路线,它们都需要一次换乘:
Stop A, Bus 2, Stop C, Bus 3, Stop D
Stop A, Bus 1, Stop B, Bus 3, Stop D
Stop A, Bus 2, Stop B, Bus 3, Stop D
当然,你可以使用 EXTRACT()
函数以任何你想要的方式返回这些信息。
另一个例子。查找从 A 到 C 的行程:
MATCH (a:Stop {name:'A'}), (c:Stop {name:'C'})
MATCH p = allShortestPaths((a)-[:STOPS_AT*]-(c))
RETURN EXTRACT(x IN NODES(p) | CASE WHEN x:Stop THEN 'Stop ' + x.name
WHEN x:Bus THEN 'Bus ' + x.id
ELSE '' END)
找到了一条路线,且无需换乘:
Stop A, Bus 2, Stop C
请告诉我这是否回答了您的问题。
编辑:要获取距离:
MATCH (a:Stop {name:'A'}), (d:Stop {name:'D'})
MATCH route = allShortestPaths((a)-[:STOPS_AT*]-(d)),
stops = (a)-[:NEXT*]->(d)
RETURN EXTRACT(x IN NODES(route) | CASE WHEN x:Stop THEN 'Stop ' + x.name
WHEN x:Bus THEN 'Bus ' + x.id
ELSE '' END) AS itinerary,
REDUCE(d = 0, x IN RELATIONSHIPS(stops) | d + x.distance) AS distance
itinerary distance
Stop A, Bus 1, Stop B, Bus 3, Stop D 6
Stop A, Bus 2, Stop B, Bus 3, Stop D 6
Stop A, Bus 2, Stop C, Bus 3, Stop D 6