我有一个带有定向循环的Neo4j图。我没有找到A
的所有后代的问题,假设我不关心使用此Cypher查询的循环:
match (n:TEST{name:"A"})-[r:MOVEMENT*]->(m:TEST)
return n,m,last(r).movement_time
我的节点之间的关系有一个时间戳属性,movement_time
。我在下面的测试数据中使用我作为浮点数导入的数字模拟了这一点。我想使用时间戳作为约束来遍历图形。仅遵循移动时间大于将我们带到此节点的关系的movement_time的关系。
以下是CSV样本数据:
from,to,movement_time
A,B,0
B,C,1
B,D,1
B,E,1
B,X,2
E,A,3
Z,B,5
C,X,6
X,A,7
D,A,7
以下是图表的样子:
我想计算图中每个节点的后代,并使用Cypher包含上一个关系的时间戳;所以我希望我的输出数据看起来像这样的东西:
Node:[{Descendant,Movement Time},...]
A:[{B,0},{C,1},{D,1},{E,1},{X,2}]
B:[{C,1},{D,1},{E,1},{X,2},{A,7}]
C:[{X,6},{A,7}]
D:[{A,7}]
E:[{A,3}]
X:[{A,7}]
Z:[{B,5}]
这个非 -Neo4J实现看起来类似于我尝试做的事情:Cycle enumeration of a directed graph with multi edges
答案 0 :(得分:1)
这个不是100%你想要的,但非常接近:
MATCH (n:TEST)-[r:MOVEMENT*]->(m:TEST)
WITH n, m, r, [x IN range(0,length(r)-2) |
(r[x+1]).movement_time - (r[x]).movement_time] AS deltas
WHERE ALL (x IN deltas WHERE x>0)
RETURN n, collect(m), collect(last(r).movement_time)
ORDER BY n.name
我们基本上可以找到任何节点之间的所有路径(注意笛卡尔积在非平凡数据集上非常昂贵)。在WITH
我们正在构建一个集合delta's
,它可以保存两个后续movement_time
属性之间的差异。
WHERE
应用ALL
谓词来过滤掉那些具有任何非正值的谓词 - 也就是说我们保证沿路径增加movement_time
值。
RETURN
然后只汇编结果 - 但不是地图,而是可达节点的一个集合和movement_time
的最后一个值。
目前的问题是我们有重复项,例如从B
到A
有多条路径。
作为一般性通知:使用Java遍历API(http://neo4j.com/docs/stable/tutorial-traversal.html)可以更好地解决此问题并提高性能。在这里,你会有一个PathExpander
跳过早期递减movement_time
的路径而不是全部收集并过滤掉(如Cypher所做的那样)。