Neo4j Cypher,在可变长度路径中从计数中排除关系

cbwuti44  于 2023-03-18  发布在  其他
关注(0)|答案(2)|浏览(121)

我们可以使用以下模式限制可变长度的FIRST|SECOND路径:

(a)-[r:FIRST|SECOND*..3]->(b)

但是,返回包含多达3个SECOND关系的FIRST|SECOND路径的最佳方法是什么?

ryhaxcpt

ryhaxcpt1#

我能想到的有两种情况。
a. SECOND是链接到B的最后一个关系,如下所示:

(a)-[:FIRST]->()-[:SECOND]->()-[:SECOND]->()-[:SECOND]->(b)

为此,您可以尝试以下查询:

MATCH path=(a)-[r:FIRST|SECOND*1..]->()-[:SECOND]->(b)
WHERE SIZE([r1 in relationships(path) WHERE type(r1) = 'SECOND' | r1]) = 3
RETURN path

在这个查询中,我修正了链接到b的最后一个关系的类型为“SECOND”,并检查SECOND关系的计数是否为3。
B.另一种情况是,任何关系都可以链接到路径末尾的b,只要路径上有3个SECOND关系。

(a)-[:SECOND]->()-[:SECOND]->()-[:SECOND]->()-[:FIRST]->(b)

对于这种情况,请尝试以下查询:

MATCH path=(a)-[r:FIRST|SECOND*1..]->(b)
 WHERE SIZE([r1 in relationships(path) WHERE type(r1) = 'SECOND' | r1]) = 3
 RETURN path

正如@cybersam在注解中所指出的,为了避免内存不足的错误,应该在模式匹配中设置一个上限,这符合您的目的,而且,如果需要最多3个SECOND关系,那么下面的查询将起作用:

MATCH path=(a)-[r:FIRST|SECOND*1..10]->(b)
 WHERE SIZE([r1 in relationships(path) WHERE type(r1) = 'SECOND' | r1]) <= 3
 RETURN path

注意,我在这里提供了一个上限10,你可以相应地修改它。

w46czmvw

w46czmvw2#

这是一个非常困难的问题,您的用例不允许可变长度路径模式有一个上限(这通常是最佳实践),因为第一个(或第二个,或第三个)SECOND关系可能出现在 * 任何数量 * 的关系之后。
虽然下面的查询没有强加任何上限,但它也不会在找到每个SECOND关系后尝试进一步扩展子路径。因此,它**避免了不必要地搜索到每个可能路径的末尾。FIRST*0..语法表示“匹配具有0个或更多连续FIRST关系的路径”。
此查询能够查找具有最多3个SECOND关系的所有路径,方法是将3个单独的子路径查询链接在一起,然后使用APOC方法apoc.path.combine将子路径缝合在一起形成最终的完整路径。NULL检查用于忽略未找到匹配的子路径。

MATCH (a:Test {testid: 1})
OPTIONAL MATCH p1=(a)-[:FIRST*0..]->()-[:SECOND]->(b)
OPTIONAL MATCH p2=(b)-[:FIRST*0..]->()-[:SECOND]->(c)
OPTIONAL MATCH p3=(c)-[:FIRST*0..]->()-[:SECOND]->(d)
WITH p1,
  CASE WHEN p2 IS NOT NULL THEN apoc.path.combine(p1, p2) END AS p12,
  CASE WHEN p3 IS NOT NULL THEN p3 END AS p3
WITH p1, p12,
  CASE WHEN p3 IS NOT NULL THEN apoc.path.combine(p12, p3) END AS p123
WITH (COLLECT(p1) + COLLECT(p12) + COLLECT(p123)) AS paths
UNWIND paths AS p
RETURN p

相关问题