Neo4j - 在foreach中永远不会结束

时间:2016-02-17 14:38:21

标签: neo4j

我有一个数据库,代表学校项目的城市地图。 每个节点代表街道中的一个点,每个关系代表一段道路,两个节点之间的距离作为属性。 我通过使用java接口解析XML文件将其导入Neo4j 但是由于XML文件的编码方式,我有很多节点没用,因为它们只是代表街道的中间位置,而不是交叉点或指示新的街道。

所以,我试图在两个交叉点之间的每个路段的极端,在这两个节点之间创建一个关系,然后总结街道的每个关系的距离。

对于这些命令中的每一个,我都使用neo4j的浏览器客户端,但是我的计算机上有一个数据库。 首先,我使用此命令标记我想要销毁的所有关系和节点:

match ()-[r]-(n)-[t]-()
with r,n,t,size(n--()) as degree
where degree=2 and r.name=t.name
set r.toDestroy=1,t.toDestroy=1,n.toDestroy=1

然后我用

获得每对重要节点
match (a)-[r* {toDestroy;1}]-(b)
where a.toDestroy is NULL and b.toDestroy is NULL and all (x in r where x.name=(r[0]).name)
return a,r,b

这个命令返回我要求的内容,所以现在我在(a)和(b)之间创建一个新的关系,并设置它的距离

match (a)-[r* {toDestroy;1}]-(b)
where a.toDestroy is NULL and b.toDestroy is NULL and all (x in r where x.name=(r[0]).name)
merge (a)-[t:TRONCON_DE_VOIE]->(b)
set t.distance=0,t.name=(r[0]).name
foreach(x in r|set t.distance=t.distance+r.distance)

这就是我的问题所在:这个请求永远不会回来,客户只是告诉我它正在运行。我不明白为什么,因为即使我隔离了两个节点及其链接,它也不起作用。如果我在foreach中添加类似(set x.distance=1)的内容,它也无法正常工作。

我在互联网上看了一下,似乎没有人和我有同样的问题。此外,如果我创建另一个数据库并用随机节点填充它并尝试类似的命令,它就会结束。所以它可能来自数据库本身,但我不明白为什么。

1 个答案:

答案 0 :(得分:0)

这可能是因为最后一个句子将调用SET N次,其中N基本上是toDestroy: 1的关系总数。

这是一个更有效的查询,根本不使用SET子句:

MATCH (a)-[r* {toDestroy:1}]-(b)
WHERE a.toDestroy is NULL AND b.toDestroy is NULL AND ALL(x in r where x.name=(r[0]).name)
WITH a, b, (r[0]).name AS name, REDUCE(s = 0, x IN r | s + x.distance) AS total
merge (a)-[t:TRONCON_DE_VOIE {distance: total, name: name}]->(b);

基本上,您应该始终尝试在内存中进行计算,而不在DB中存储临时值。

[编辑]

顺便说一下,可变长度路径搜索可以很容易地永远运行"和/或内存不足,因为它们具有指数复杂性。如果路径上每个节点的平均关系数为R,并且搜索深度为d,则不同路径的数量大致为R^d。因此,通常,您希望通过指定可接受的" small"来限制可变长度路径搜索的深度。上限,如:

MATCH (a)-[r*..10 {toDestroy:1}]-(b)