我有一个代表学校项目的城市地图的数据库。每个节点代表街道上的一个点,每个关系代表一段道路,两个节点之间的距离是一个属性。我通过解析带有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)
这就是我的问题所在:这个请求永远不会返回,客户只需告诉我它正在运行。我不明白为什么,因为即使我隔离了两个节点和它们的链接,它也不起作用。如果我把(set x.distance=1
)之类的东西放在前额,它也不起作用。
我在网上看了看,似乎没有人和我有同样的问题。此外,如果我创建另一个DB并使用随机节点填充它并尝试一个类似的命令,它就会结束。所以它可能来自DB本身,但我只是不明白为什么。
发布于 2016-02-17 12:21:27
这可能是因为最后一个子句将调用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
。因此,通常,您希望通过指定一个可接受的“小”上限来限制可变长度路径搜索的深度,如下所示:
MATCH (a)-[r*..10 {toDestroy:1}]-(b)
https://stackoverflow.com/questions/35459690
复制相似问题