【问题标题】:Neo4j ShortestPath duplicate propertiesNeo4j ShortestPath 重复属性
【发布时间】:2018-09-17 13:01:45
【问题描述】:

我目前正在使用 Neo4j 的内置最短路径算法。

MATCH p = shortestpath((s:Node {Name: "A"})-[Link*1..500]->(e:Node {Name: "B"})) 
WHERE ALL(x in relationships(p) WHERE x.Value = true)
RETURN p

问题是,当我运行算法时,尽管通过了第一个“B”(橙色线),它仍然可以返回第二个“B”。我如何让它只返回“B”的第一个实例?

我知道我可以通过使用唯一 ID 来简单地解决问题,但我需要使用名称。

public class Node
{
   public long Id {get;set;}
   public string Name {get;set;}
   public long X {get;set;}
   public long Y {get;set;}
}

public class Link {
   public bool Value {get;set;}
   public long Length {get;set;}
}

提前致谢,欢迎随时提问。

【问题讨论】:

  • 对不起,我不明白您查询的结果是什么,以及您想要什么结果。你能更准确地描述一下吗?
  • 当前查询返回橙色线,但我希望它在到达名为 B 的第一个节点时返回。我回家后会更新图像以包含我想要的内容。
  • 所以它应该只触及一个名为“B”的节点作为路径的最后一个节点?
  • 它不应该返回最后一个 B,因为它已经通过了一个名为 B 的节点。它应该返回 (a)-()-()-()-(b) 而不是 (a )-()-()-()-(b)-(b)
  • @Liam 您现在的查询正在按预期工作,因此为了排除第二个“B”节点,您需要更新过滤器逻辑以说明该路径为何无效.因此,正确答案取决于您需要添加的确切限制是什么。听起来您不希望中间节点也具有名称“B”。不知道上图中空白节点的故事是什么,所以不知道是不是真的。如果我理解正确,您需要将AND (x = e OR x.name <> "B") 添加到您的过滤器中,以便只有最后一个节点被命名为“B”

标签: neo4j cypher


【解决方案1】:

使用您的查询,neo4j 将找到每个 A 节点和每个 B 节点,然后找到从每个 A 到每个 B 的所有最短路径。在控制台 UI 中呈现的是来自该查询的所有结果节点以及连接每个节点的每个关系。如果您单击查询窗口左侧的 _Text_ 按钮,将会更清楚正在发生的事情。您将看到 A dn B 节点之间匹配的每条最短路径的谨慎行。

阅读您的问题后,我希望您所追求的是与特定 A 节点匹配的查询,然后遍历直到遇到 B 节点。

apoc 路径扩展过程调用可能更适合您的需要。如果您可以将标签B 添加到B 节点,那么您可以使用apoc.path.expand 来查找您正在寻找的路径。

您可以使用以下设置B标签。

MATCH (n:Node {Name: 'B'}
SET n:B

这是一个使用 apoc.path.expand 的示例查询,它应该在遇到的第一个 B 节点处停止。

MATCH (a:Node {Name: 'A'})
WITH a
CALL apoc.path.expand(a, 'Link', '+Node|/B', 1, 500) YIELD path
RETURN path

【讨论】:

  • 你回答的第一部分为我提供了使用reduce函数的解决方案。我补充说: WITH p, reduce(s = 0, r IN Relations(p) | s + r.Length) AS dist RETURN p AS shortestPath ORDER BY dist ASC LIMIT 1
猜你喜欢
  • 2018-08-12
  • 2015-09-02
  • 2021-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-21
  • 2019-12-31
  • 1970-01-01
相关资源
最近更新 更多