gpt4 book ai didi

neo4j - 如何要求 Neo4j 考虑周期

转载 作者:行者123 更新时间:2023-12-05 01:26:54 25 4
gpt4 key购买 nike

Neo4j 似乎有意省略了循环,所以这样的查询:

MATCH (n1)-[:R]->(n2)<-[:R]-(n1)
RETURN n1, n2;

除非存在类型为 R 的两个关系,否则始终不返回任何内容在 n1 之间和 n2 (这是绝对可能的,而且是一个糟糕的黑客攻击)。

但我有一个场景,在这个场景中,这个循环可能会发生,而且这是需要的:

MATCH (n1)-[:R]->(n2)<-[:R]-(n3)
RETURN n1, n2, n3;

在此查询中,n1n3可能是相同的节点或不同的节点,这完全取决于数据(两者都有效)。一种实现方法如下:

MATCH (n1)-[:R]->(n2)
MATCH (n2)<-[:R]-(n3)
RETURN n1, n2, n3;

最后一个查询将包括所有路径甚至循环,这完全没问题。但我的情况甚至比这更复杂:

MATCH (n0)
OPTIONAL MATCH (n0)-[:R0]->(n1)-[:R]->(n2)<-[:R]-(n3)
RETURN n0, n1, n2, n3;

正如我们之前看到的,此查询中省略了循环,因此我们必须将其分解为两个 OPTIONAL MATCH是:

MATCH (n0)
OPTIONAL MATCH (n0)-[:R0]->(n1)-[:R]->(n2)
OPTIONAL MATCH (n2)<-[:R]-(n3)
RETURN n0, n1, n2, n3;

但这和以前不一样了(如果另一个有效的话)。这是第二个 OPTIONAL MATCH可能不会返回任何路径,而第一个返回。也就是说,这两个 OPTIONAL MATCH es是独立的。

所以我的问题是:如何实现以下查询并在结果中获取周期?

MATCH (n0)
OPTIONAL MATCH (n0)-[:R0]->(n1)-[:R]->(n2)<-[:R]-(n3)
RETURN n0, n1, n2, n3;

希望不要太困惑!

为什么是两个 OPTIONAL MATCH es 不是答案

考虑以下节点和关系:

  1. CREATE (n0:S)-[:R]->(n1:R)<-[:R]-(n2:E)-[:R]->(n3:R:L);
  2. CREATE (n0:S)-[:R]->(n1:R:L)<-[:R]-(n2:E);
  3. CREATE (n0:S)-[:R]->(n1:R)<-[:R]-(n2:E);

在上面的示例中,以下是标签的含义(因此您可以联系到问题):

  • :S起始节点
  • :R修改
  • :E实体
  • :L最新的作为最新的修订版

在此示例中,每条数据记录都在 :E 中表示+ :R当记录更新时,一个新的 :R被添加到它。数据的当前状态标记为 :L这样我们就可以找到最新的修订版。

现在,在给出的三个示例中,最后一个是无效数据,因为它没有任何:L。 .第一个有两次修订,第二个有一个。

请求的查询应该:

  1. 返回:S不管
  2. 返回所有实体及其最新修订版,前提是它们有最新修订版
  3. 没有最新版本的实体是没有意义的,根本不应该返回

如果 Neo4j 支持循环,此查询将返回请求的数据:

MATCH (n1:S)
OPTIONAL MATCH (n1)-[:R]->(n2:R)<-[:R]-(n3:E)-[:R]->(n4:R:L)
RETURN labels(n1), labels(n3), labels(n4);

上述查询的预期结果是:

╒════════════╤════════════╤════════════╕
│"labels(n1)"│"labels(n3)"│"labels(n4)"│
╞════════════╪════════════╪════════════╡
│["S"] │["E"] │["R","L"] │
├────────────┼────────────┼────────────┤
│["S"] │["E"] │["R","L"] │
├────────────┼────────────┼────────────┤
│["S"] │null │null │
└────────────┴────────────┴────────────┘

实际结果是:

╒════════════╤════════════╤════════════╕
│"labels(n1)"│"labels(n3)"│"labels(n4)"│
╞════════════╪════════════╪════════════╡
│["S"] │["E"] │["R","L"] │
├────────────┼────────────┼────────────┤
│["S"] │null │null │
├────────────┼────────────┼────────────┤
│["S"] │null │null │
└────────────┴────────────┴────────────┘

如您所见,第二条路径被缩短了,因为它包含一个循环。现在如果我们使用两个 OPTIONAL MATCH方法:

MATCH (n1:S)
OPTIONAL MATCH (n1)-[:R]->(n2:R)<-[:R]-(n3:E)
OPTIONAL MATCH (n3)-[:R]->(n4:R:L)
RETURN labels(n1), labels(n3), labels(n4);

结果是:

╒════════════╤════════════╤════════════╕
│"labels(n1)"│"labels(n3)"│"labels(n4)"│
╞════════════╪════════════╪════════════╡
│["S"] │["E"] │["R","L"] │
├────────────┼────────────┼────────────┤
│["S"] │["E"] │["R","L"] │
├────────────┼────────────┼────────────┤
│["S"] │["E"] │null │
└────────────┴────────────┴────────────┘

虽然第二种情况是固定的,但第三种情况现在是问题,这是因为两个可选子句可以独立存在。

抱歉,问题很长,我尽量简短!

最佳答案

如果我对问题的理解正确,此查询应该会为您提供您正在查找的预期结果表:

MATCH (n1:S)
OPTIONAL MATCH (n1)-[:R]->(n2:R)<-[:R]-(n3:E)
WHERE (n3)-[:R]->(:R:L)
OPTIONAL MATCH (n3)-[:R]->(n4:R:L)
RETURN labels(n1), labels(n3), labels(n4)

关键是我们给第一个可选匹配项的 WHERE。仅当 n3 具有到 :R:L 节点的所需路径时,OPTIONAL MATCH 才会匹配,并且它将计算 OPTIONAL MATCH 已经遍历的关系和节点。

关于neo4j - 如何要求 Neo4j 考虑周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42059081/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com