Создание кратчайшего пути с Apache AGE
Я читал сообщение в блоге Джаспера Блюза: ROCK 'N' ROLL TRAFFIC ROUTING, WITH NEO4J , но я хотел перенести его на AGE. Он строит граф с несколькими вершинами, помеченными какMetro
и каждая вершина соединена с другой ребром, обозначенным какHAS_ROUTE
и содержитtravelTime
свойство. Вот созданные вершины и ребра:
CREATE (cavite:Metro {name: 'Cavite Island'})
CREATE (stGermain:Metro {name: 'St Germain'})
CREATE (pigalle:Metro {name: 'Pigalle'})
CREATE (montreal:Metro {name: 'Montreal'})
CREATE (quebec:Metro {name: 'Quebec'})
CREATE (fortTilden:Metro {name: 'Fort Tilden'})
CREATE (intramuros:Metro {name: 'Intramuros'})
CREATE (chinaTown:Metro {name: 'China Town'})
CREATE (stDomingo:Metro {name: 'St Domingo'})
CREATE (coneyIsland:Metro {name: 'Coney Island'})
CREATE (brooklyn:Metro {name: 'Brooklyn'})
CREATE (uptown:Metro {name: 'Uptown'})
CREATE (cardShark:Metro {name: 'Card Shark'})
CREATE (divisoria:Metro {name: 'Divisoria'})
CREATE (ermita:Metro {name: 'Ermita'})
CREATE (nyc:Metro {name: 'NYC'})
CREATE (staIsabel:Metro {name: 'Sta Isabel'})
CREATE (theRuins:Metro {name: 'The Ruins'})
CREATE (phoenix:Metro {name: 'Phoenix'})
CREATE (bastille:Metro {name: 'Bastille'})
CREATE (puertoDelPostigo:Metro {name: 'Puerto del Postigo'})
CREATE (redLight:Metro {name: 'Red Light'})
CREATE (hotelStPaul:Metro {name: 'Hotel St Paul'})
CREATE (cavite)-[:HAS_ROUTE {travelTime: 2.5}]->(intramuros)
CREATE (cavite)-[:HAS_ROUTE {travelTime: 3}]->(fortTilden)
CREATE (stGermain)-[:HAS_ROUTE {travelTime: 9}]->(intramuros)
CREATE (stGermain)-[:HAS_ROUTE {travelTime: 5.6}]->(chinaTown)
CREATE (pigalle)-[:HAS_ROUTE {travelTime: 6}]->(chinaTown)
CREATE (pigalle)-[:HAS_ROUTE {travelTime: 4}]->(montreal)
CREATE (pigalle)-[:HAS_ROUTE {travelTime: 8.5}]->(nyc)
CREATE (montreal)-[:HAS_ROUTE {travelTime: 3}]->(quebec)
CREATE (fortTilden)-[:HAS_ROUTE {travelTime: 13}]->(brooklyn)
CREATE (coneyIsland)-[:HAS_ROUTE {travelTime: 1.5}]->(brooklyn)
CREATE (brooklyn)-[:HAS_ROUTE {travelTime: 2.5}]->(uptown)
CREATE (brooklyn)-[:HAS_ROUTE {travelTime: 5}]->(theRuins)
CREATE (uptown)-[:HAS_ROUTE {travelTime: 5}]->(intramuros)
CREATE (intramuros)-[:HAS_ROUTE {travelTime: 11}]->(chinaTown)
CREATE (intramuros)-[:HAS_ROUTE {travelTime: 16.5}]->(bastille)
CREATE (chinaTown)-[:HAS_ROUTE {travelTime: 7.5}]->(divisoria)
CREATE (chinaTown)-[:HAS_ROUTE {travelTime: 4.5}]->(ermita)
CREATE (chinaTown)-[:HAS_ROUTE {travelTime: 12.5}]->(nyc)
CREATE (theRuins)-[:HAS_ROUTE {travelTime: 4}]->(cardShark)
CREATE (theRuins)-[:HAS_ROUTE {travelTime: 5.5}]->(phoenix)
CREATE (theRuins)-[:HAS_ROUTE {travelTime: 2.5}]->(redLight)
CREATE (cardShark)-[:HAS_ROUTE {travelTime: 4.5}]->(phoenix)
CREATE (divisoria)-[:HAS_ROUTE {travelTime: 6.5}]->(bastille)
CREATE (ermita)-[:HAS_ROUTE {travelTime: 9}]->(puertoDelPostigo)
CREATE (nyc)-[:HAS_ROUTE {travelTime: 10.5}]->(puertoDelPostigo)
CREATE (nyc)-[:HAS_ROUTE {travelTime: 5}]->(stDomingo)
CREATE (nyc)-[:HAS_ROUTE {travelTime: 2}]->(staIsabel)
CREATE (phoenix)-[:HAS_ROUTE {travelTime: 3.5}]->(redLight)
CREATE (phoenix)-[:HAS_ROUTE {travelTime: 10}]->(bastille)
CREATE (bastille)-[:HAS_ROUTE {travelTime: 6.5}]->(hotelStPaul)
CREATE (bastille)-[:HAS_ROUTE {travelTime: 6}]->(puertoDelPostigo)
CREATE (puertoDelPostigo)-[:HAS_ROUTE {travelTime: 3}]->(staIsabel)
Затем в разделе НАИБОЛЕЕ ВЫГОДНЫЙ РАЗБОР есть такой запрос:
MATCH paths = (a:Metro {name: 'Cavite Island'})-[:HAS_ROUTE*1..6]-(b:Metro {name: 'NYC'})
WITH paths, relationships(paths) AS rels
UNWIND rels AS rel
WITH [metro IN nodes(paths) | metro.name] AS metros,
collect(rel.travelTime) AS streets,
sum(rel.travelTime) AS travelTime
ORDER BY travelTime
RETURN metros, streets, travelTime
Но когда я запускаю его на AGE, он выдает следующую ошибку:
SELECT * from cypher('Saxeburg', $$
MATCH paths = (a:Metro {name: 'Cavite Island'})-[:HAS_ROUTE*1..6]-(b:Metro {name: 'NYC'})
WITH paths, relationships(paths) AS rels
UNWIND rels AS rel
WITH [metro IN nodes(paths) | metro.name] AS metros, collect(rel.travelTime) AS streets, sum(rel.travelTime) AS travelTime
ORDER BY travelTime
RETURN metros, streets, travelTime
$$) as (metros agtype, streets agtype, travelTime agtype);
-- Syntax error at or near "|"
-- Removing the "|" throws another error : Could not find rte for metro
Другой метод, который я пробовал, заключался в выполнении запроса ниже, но он выдаетERROR: syntax error at or near "|"
.
SELECT * FROM cypher('demo', $$
MATCH (from:Metro {name:'Brooklyn'}), (to:Metro {name:'Phoenix'}), path = (from)-[:HAS_ROUTE]->(to)
RETURN path AS shortestPath,
reduce(travelTime = 0, r in relationships(path) | travelTime+r.travelTime; 0) AS totalTravelTime
$$) as (totalTravelTime agtype);
Как я могу правильно выполнить этот запрос, чтобы получить кратчайший путь от одной вершины к другой?
2 ответа
The |
символ в настоящее время не распознается AGE. Вы сможете получить аналогичный результат, заменив[metro IN nodes(paths) | metro.name] AS metros
сnodes(paths) AS nodes
. Единственное отличие состоит в том, что при этом будут выведены все свойства каждого узла, а не только их имена.
SELECT * FROM cypher('Saxeburg', $$
MATCH paths = (a:Metro {name: 'Cavite Island'})-[:HAS_ROUTE*1..6]->(b:Metro {name: 'NYC'})
WITH paths, relationships(paths) AS rels
UNWIND rels AS rel
WITH nodes(paths) AS nodes,
collect(rel.travelTime) AS streets,
sum(rel.travelTime) AS travelTime
RETURN nodes, streets, travelTime
$$) AS (metros agtype, streets agtype, travelTime agtype)
ORDER BY travelTime;
Многие функции AGE db находятся в стадии разработки. Но вы можете попробовать этот пакет python для реализации кратчайшего parh с использованием apache AGE.