You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Apache AGE中正确执行基于travelTime的最短路径查询

Apache AGE中实现Neo4j交通路由的最短路径查询

我正在将一篇博客中的Neo4j交通路由逻辑移植到Apache AGE中:构建一个包含Metro标签顶点和HAS_ROUTE标签边的图,边带有travelTime属性表示通行时间。原Neo4j的最短路径查询在Apache AGE中执行时出现语法错误,需要调整写法以正确获取两点间的最短路径。

原Neo4j查询:

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

在Apache AGE中执行时报错Syntax error at or near "|",尝试带reduce的写法也报同样错误。


语法差异说明

Apache AGE的Cypher实现与标准Neo4j Cypher存在部分语法差异:

  • 不支持[item IN list | item.property]这种列表推导式语法
  • reduce函数无需重复末尾的初始值参数

正确查询写法

方式1:枚举所有路径并按总时间排序

与原Neo4j查询逻辑一致,通过拆解列表推导式实现:

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 paths, collect(rel.travelTime) AS streets, sum(rel.travelTime) AS travelTime
    UNWIND nodes(paths) AS metro
    WITH paths, streets, travelTime, collect(metro.name) AS metros
    ORDER BY travelTime
    RETURN metros, streets, travelTime
$$) as (metros agtype, streets agtype, travelTime agtype);

方式2:使用最短路径函数(更高效)

如果仅需最短时间路径,推荐使用Apache AGE的图算法函数,效率更高:

SELECT * from cypher('Saxeburg', $$
    MATCH (start:Metro {name: 'Cavite Island'}), (end:Metro {name: 'NYC'})
    CALL gds.shortestPath.dijkstra.stream({
        nodeProjection: 'Metro',
        relationshipProjection: {
            HAS_ROUTE: {
                type: 'HAS_ROUTE',
                properties: 'travelTime',
                orientation: 'UNDIRECTED'
            }
        },
        startNode: start,
        endNode: end,
        relationshipWeightProperty: 'travelTime'
    })
    YIELD nodeIds, totalCost
    WITH [nodeId IN nodeIds | gds.util.asNode(nodeId).name] AS metros, totalCost AS travelTime
    RETURN metros, travelTime
$$) as (metros agtype, travelTime agtype);

修正reduce函数的写法

若需手动计算路径总时间,AGE中reduce的正确语法如下:

SELECT * FROM cypher('demo', $$
    MATCH path = (from:Metro {name:'Brooklyn'})-[:HAS_ROUTE*]-(to:Metro {name:'Phoenix'})
    RETURN path AS shortestPath,
           reduce(travelTime = 0, r IN relationships(path) | travelTime + r.travelTime) AS totalTravelTime
    ORDER BY totalTravelTime
    LIMIT 1
$$) as (shortestPath agtype, totalTravelTime agtype);

内容的提问来源于stack exchange,提问作者Matheus Farias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 03:27:39