Neo4j Cypher遍历——通过多种关系类型查找路径
Neo4j Cypher traversal - find path by multiple relationship types
我有一个架构,其中节点通过两种类型的关系连接 - r:A 和 r:B。我正在尝试编写一个模式,它将找到从节点 N 到节点 M 的每条路径。这可以通过以下密码查询简单地完成:
match path = (n)-[:A|:B*]->(m) return path;
不幸的是,这不是我真正需要的。我需要找到从 (n) 到 (m) 的每条路径,其中通过关系 r:A 的深度可以是无限的,但沿途只能使用有限数量的 r:B 关系。在快乐的一天场景中,密码查询将如下所示:
match path = (n)-[:A*|:B*0..3]->(m) return path;
但是密码不允许这种语法。即使在途中使用另一个 "helping" 节点,我也无法解决这个问题:
match path = (n)-[:A*]->()-[:B*0..3]->(m) return path;
这也不符合我的需要,因为节点可以以任何可能的方式互连。例如:
(n)-[r:A]-()-[r:A]-()-[r:A]-(m)
(n)-[r:A]-(m)
(n)-[r:A]-()-[r:B]-()-[r:A]-()-[r:B]-()-[r:A]-()-[r:A]-(m)
有什么办法可以实现吗?如果不在 cypher 中,是否可以在 gremlin / neo4j 遍历 api / spring 数据 neo4j 项目的嵌入式函数中完成?
感谢您的回答。
试试这个:
MATCH path = (n)-[:A|:B*]->(m)
WITH path, relationships(path) AS r,
filter(rel in relationships(path)
WHERE type(rel) = 'B') AS Brels
WITH path, reduce(Bcount = 0, rel IN Brels | Bcount + 1) AS Bcount
WHERE Bcount <= 3
RETURN path
不知道我是不是把问题理解的很清楚了。请告诉我。
编辑:
我在评论后添加了第二个查询。这个解决方案很丑陋,但它是一个很好的解决方法。
MATCH path = (n)-[:A|:B*]-(m)
WITH path, filter(rel in
relationships(path) WHERE type(rel) = 'B') AS Brels
WITH path,
reduce(Bcount = 0, rel IN Brels | Bcount + 1) AS Bcount
WHERE Bcount
<= 3
WITH path, relationships(path) AS rels
WITH path, rels,
reduce(count = 0, rel IN rels | count + 1) AS count
WITH path, rels,
range(0,count-1) as counter
WITH path, reduce(x = 0, c IN counter |
CASE WHEN (type(rels[c])='B' AND type(rels[c+1])='B') THEN x+200000
ELSE x+1 END) AS countX
WHERE countX<200000
RETURN path, countX
我有一个架构,其中节点通过两种类型的关系连接 - r:A 和 r:B。我正在尝试编写一个模式,它将找到从节点 N 到节点 M 的每条路径。这可以通过以下密码查询简单地完成:
match path = (n)-[:A|:B*]->(m) return path;
不幸的是,这不是我真正需要的。我需要找到从 (n) 到 (m) 的每条路径,其中通过关系 r:A 的深度可以是无限的,但沿途只能使用有限数量的 r:B 关系。在快乐的一天场景中,密码查询将如下所示:
match path = (n)-[:A*|:B*0..3]->(m) return path;
但是密码不允许这种语法。即使在途中使用另一个 "helping" 节点,我也无法解决这个问题:
match path = (n)-[:A*]->()-[:B*0..3]->(m) return path;
这也不符合我的需要,因为节点可以以任何可能的方式互连。例如:
(n)-[r:A]-()-[r:A]-()-[r:A]-(m)
(n)-[r:A]-(m)
(n)-[r:A]-()-[r:B]-()-[r:A]-()-[r:B]-()-[r:A]-()-[r:A]-(m)
有什么办法可以实现吗?如果不在 cypher 中,是否可以在 gremlin / neo4j 遍历 api / spring 数据 neo4j 项目的嵌入式函数中完成?
感谢您的回答。
试试这个:
MATCH path = (n)-[:A|:B*]->(m)
WITH path, relationships(path) AS r, filter(rel in relationships(path)
WHERE type(rel) = 'B') AS Brels
WITH path, reduce(Bcount = 0, rel IN Brels | Bcount + 1) AS Bcount
WHERE Bcount <= 3
RETURN path
不知道我是不是把问题理解的很清楚了。请告诉我。
编辑:
我在评论后添加了第二个查询。这个解决方案很丑陋,但它是一个很好的解决方法。
MATCH path = (n)-[:A|:B*]-(m)
WITH path, filter(rel in relationships(path) WHERE type(rel) = 'B') AS Brels
WITH path, reduce(Bcount = 0, rel IN Brels | Bcount + 1) AS Bcount
WHERE Bcount <= 3
WITH path, relationships(path) AS rels
WITH path, rels, reduce(count = 0, rel IN rels | count + 1) AS count
WITH path, rels, range(0,count-1) as counter
WITH path, reduce(x = 0, c IN counter |
CASE WHEN (type(rels[c])='B' AND type(rels[c+1])='B') THEN x+200000 ELSE x+1 END) AS countX
WHERE countX<200000
RETURN path, countX