使用关系属性作为过滤器的带有定向循环的导线图

时间:2015-10-13 14:01:59

标签: graph neo4j

我有一个带有定向循环的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

以下是图表的样子:

Graph

我想计算图中每个节点的后代,并使用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

1 个答案:

答案 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的最后一个值。

目前的问题是我们有重复项,例如从BA有多条路径。

作为一般性通知:使用Java遍历API(http://neo4j.com/docs/stable/tutorial-traversal.html)可以更好地解决此问题并提高性能。在这里,你会有一个PathExpander跳过早期递减movement_time的路径而不是全部收集并过滤掉(如Cypher所做的那样)。