具有中间节点的 Cypher 匹配路径
Cypher match path with intermediate nodes
我有下图,其中包含 Stop
(红色)和 Connection
(绿色)节点。
我想在 Connection
上使用成本 属性 找到从 A
到 C
的最短路径。
我想避免与 Connection
建立关系,因为我失去了 Foo
的 CONTAINS
关系。
我可以这样匹配单跳
MATCH p=(:Stop {name:'A'})<-[:BEGINS_AT]-(:Connection)-[:ENDS_AT]->(:Stop {name:'B'}) RETURN p
但这不适用于任意数量的 Connection
,就像关系和 [*]
.
我也尝试将预测归结为简单的关系,但似乎没有 GDS 我无法做任何事情。
MATCH (s1:Stop)<-[:BEGINS_AT]-(c:Connection)-[:ENDS_AT]->(s2:Stop) RETURN id(s1) AS source, id(s2) AS target, c.cost AS cost
注意连接是单向的,所以一定不可能从C
到A
。
有没有办法在没有任何 Neo4j 插件的情况下做到这一点?
如果要计算加权最短路径,那么使用GDS甚至APOC插件是最简单的。您可能可以使用密码创建最短加权路径函数,但不会对其进行优化。我只能想到找到两个节点之间的所有路径并对权重求和。在下一步中,您将过滤具有最小权重总和的路径。不过,这不会很好地扩展。
至于你问题的第二部分,我需要更多信息,因为我不知道你到底想要什么。
这应该得到所有可用的路径(没有插件):
WITH ['BEGINS_AT', 'ENDS_AT'] AS types
MATCH p=(a:Stop)-[:BEGINS_AT|ENDS_AT*]-(b:Stop)
WHERE a.name = 'A' AND b.name = 'B' AND
ALL(i IN RANGE(0, LENGTH(p)-1) WHERE TYPE(RELATIONSHIPS(p)[i]) = types[i%2])
RETURN p
求最短路径:
WITH ['BEGINS_AT', 'ENDS_AT'] AS types
MATCH p=(a:Stop)-[:BEGINS_AT|ENDS_AT*]-(b:Stop)
WHERE a.name = 'A' AND b.name = 'B' AND
ALL(i IN RANGE(0, LENGTH(p)-1) WHERE TYPE(RELATIONSHIPS(p)[i]) = types[i%2])
RETURN p
ORDER BY LENGTH(p)
LIMIT 1;
或
WITH ['BEGINS_AT', 'ENDS_AT'] AS types
MATCH p=shortestpath((a:Stop)-[:BEGINS_AT|ENDS_AT*]-(b:Stop))
WHERE a.name = 'A' AND b.name = 'B' AND
ALL(i IN RANGE(0, LENGTH(p)-1) WHERE TYPE(RELATIONSHIPS(p)[i]) = types[i%2])
RETURN p
我有下图,其中包含 Stop
(红色)和 Connection
(绿色)节点。
我想在 Connection
上使用成本 属性 找到从 A
到 C
的最短路径。
我想避免与 Connection
建立关系,因为我失去了 Foo
的 CONTAINS
关系。
我可以这样匹配单跳
MATCH p=(:Stop {name:'A'})<-[:BEGINS_AT]-(:Connection)-[:ENDS_AT]->(:Stop {name:'B'}) RETURN p
但这不适用于任意数量的 Connection
,就像关系和 [*]
.
我也尝试将预测归结为简单的关系,但似乎没有 GDS 我无法做任何事情。
MATCH (s1:Stop)<-[:BEGINS_AT]-(c:Connection)-[:ENDS_AT]->(s2:Stop) RETURN id(s1) AS source, id(s2) AS target, c.cost AS cost
注意连接是单向的,所以一定不可能从C
到A
。
有没有办法在没有任何 Neo4j 插件的情况下做到这一点?
如果要计算加权最短路径,那么使用GDS甚至APOC插件是最简单的。您可能可以使用密码创建最短加权路径函数,但不会对其进行优化。我只能想到找到两个节点之间的所有路径并对权重求和。在下一步中,您将过滤具有最小权重总和的路径。不过,这不会很好地扩展。
至于你问题的第二部分,我需要更多信息,因为我不知道你到底想要什么。
这应该得到所有可用的路径(没有插件):
WITH ['BEGINS_AT', 'ENDS_AT'] AS types
MATCH p=(a:Stop)-[:BEGINS_AT|ENDS_AT*]-(b:Stop)
WHERE a.name = 'A' AND b.name = 'B' AND
ALL(i IN RANGE(0, LENGTH(p)-1) WHERE TYPE(RELATIONSHIPS(p)[i]) = types[i%2])
RETURN p
求最短路径:
WITH ['BEGINS_AT', 'ENDS_AT'] AS types
MATCH p=(a:Stop)-[:BEGINS_AT|ENDS_AT*]-(b:Stop)
WHERE a.name = 'A' AND b.name = 'B' AND
ALL(i IN RANGE(0, LENGTH(p)-1) WHERE TYPE(RELATIONSHIPS(p)[i]) = types[i%2])
RETURN p
ORDER BY LENGTH(p)
LIMIT 1;
或
WITH ['BEGINS_AT', 'ENDS_AT'] AS types
MATCH p=shortestpath((a:Stop)-[:BEGINS_AT|ENDS_AT*]-(b:Stop))
WHERE a.name = 'A' AND b.name = 'B' AND
ALL(i IN RANGE(0, LENGTH(p)-1) WHERE TYPE(RELATIONSHIPS(p)[i]) = types[i%2])
RETURN p