基本工作流程
图中最常见的问题之一是在节点之间查找最短路径。此示例演示如何从 Neo4j 数据创建 GDS 图、运行路径查找算法并将结果写回 Neo4j。
创建图
以下 Cypher 查询在 Neo4j 数据库中创建了一个小型火车网络图。每个关系都包含一个表示两个站点之间距离的 `distance` 数值属性。
CREATE
// Add the stations
(a:Station {name: 'Kings Cross'}),
(b:Station {name: 'Euston'}),
(c:Station {name: 'Camden Town'}),
(d:Station {name: 'Mornington Crescent'}),
(e:Station {name: 'Kentish Town'}),
// Add the connections between stations
(a)-[:CONNECTION {distance: 0.7}]->(b),
(b)-[:CONNECTION {distance: 1.3}]->(c),
(b)-[:CONNECTION {distance: 0.7}]->(d),
(d)-[:CONNECTION {distance: 0.6}]->(c),
(c)-[:CONNECTION {distance: 1.3}]->(e)
图如下所示
下一个查询从 `:Station` 节点和 `:CONNECTION` 关系及其 `distance` 属性创建了一个名为 `trainGraph` 的内存图。
MATCH (source:Station)-[r:CONNECTION]->(target:Station)
RETURN gds.graph.project(
'trainGraph',
source,
target,
{ relationshipProperties: r { .distance } }
)
在 `stream` 模式下运行算法
计算图中最短路径的一个好的第一个候选算法是 Dijkstra 源-目标最短路径 算法。要试用它,请使用 `stream` 模式 来查看查询输出中的结果。
MATCH (1)
(source:Station {name: 'Kings Cross'}),
(target:Station {name: 'Kentish Town'})
CALL gds.shortestPath.dijkstra.stream( (2)
'trainGraph', (3)
{ (4)
sourceNode: source,
targetNode: target,
relationshipWeightProperty: 'distance'
}
)
YIELD (5)
index,
sourceNode,
targetNode,
totalCost,
path
RETURN (6)
index,
gds.util.asNode(sourceNode).name AS sourceNodeName,
gds.util.asNode(targetNode).name AS targetNodeName,
totalCost,
nodes(path) AS path
ORDER BY index
1 | `MATCH` 子句定义源节点和目标节点。 |
2 | `gds.shortestPath.dijkstra` 算法在 `stream` 模式下运行。 |
3 | 要在其上运行算法的投影图的名称。 |
4 | 算法的 语法部分(`Stream 模式` 面板)中列出的配置参数。 |
5 | 算法的 语法部分(`Stream 模式` 面板)中列出的结果字段。仅包含您需要的字段。 |
6 | 查询结果字段,通常是 `YIELD` 子句中的结果字段,包装在 Cypher 函数中。 `gds.util.asNode()` 函数检索与投影节点对应的 Neo4j 节点。在路径查找算法的情况下,`nodes()` Cypher 函数用于将节点路径作为节点列表返回。 |
索引 | 源节点名称 | 目标节点名称 | 总成本 | 路径 |
---|---|---|---|---|
0 |
"国王十字" |
"肯蒂什镇" |
3.3 |
[节点[0],节点[1],节点[2],节点[4]] |
写入结果
如果算法的结果符合预期,则下一步可以将它们写回 Neo4j 数据库。以下查询与 `stream` 查询非常相似,除了添加了一些特定于 `write` 模式的配置参数以及结果的不同格式。
MATCH (1)
(source:Station {name: 'Kings Cross'}),
(target:Station {name: 'Kentish Town'})
CALL gds.shortestPath.dijkstra.write( (2)
'trainGraph', (3)
{ (4)
sourceNode: source,
targetNode: target,
relationshipWeightProperty: 'distance',
writeRelationshipType: 'PATH',
writeNodeIds: true,
writeCosts: true
}
)
YIELD relationshipsWritten
RETURN relationshipsWritten
1 | `MATCH` 子句定义源节点和目标节点。 |
2 | `gds.shortestPath.dijkstra` 算法在 `write` 模式下运行。 |
3 | 投影图的名称。 |
4 | 算法的 语法部分(`Write 模式` 面板)中列出的配置参数。在本例中,使用三个参数 `writeRelationshipType`、`writeNodeIds` 和 `writeCosts` 来创建新的 `:PATH` 关系及其 `totalCost`、`nodeIds` 和 `costs` 属性。 |
已写入的关系数 |
---|
1 |
查询 Neo4j 数据库
要检查算法的结果是否已正确写回 Neo4j,您可以运行一个 Cypher 查询,该查询包括上一步中写入的新关系和关系属性(在本例中,`PATH` 关系及其 `nodeIds`、`costs` 和 `totalCost` 属性)。
MATCH (source)-[r:PATH]->(target)
RETURN
source.name,
[nodeId IN r.nodeIds | gds.util.asNode(nodeId).name] AS nodeNames,
r.costs,
r.totalCost,
target.name
源节点名称 | 节点名称 | 关系成本 | 关系总成本 | 目标节点名称 |
---|---|---|---|---|
"国王十字" |
["国王十字","尤斯顿","卡姆登镇","肯蒂什镇"] |
[0.0, 0.7, 2.0, 3.3] |
3.3 |
"肯蒂什镇" |
后续步骤
此示例介绍了使用 GDS 算法的基础知识。 下一个示例 显示了一个完整的端到端工作流程,包括将算法的输出与另一个算法一起使用。