在路径上合并节点计算关系的(复合)属性

时间:2016-05-29 10:50:50

标签: neo4j cypher

(使用Neo4j 3.x和neo4j.v1 Python驱动程序)

我有一个由节点链接组成的轨道,每个节点代表一对(lon,lat)坐标。

(A)-[:NEXT]->(B)-[:NEXT]->(C) etc. with properties lon, lat on each node

问题1

两个相邻节点的坐标之间的直接距离,例如(0,0)和(1,1),可以作为关系的“距离”属性添加 - [:NEXT {距离:1.41421}] - >在两个相邻节点之间。鉴于我有这样的数千个节点,你怎么能这样做呢?

From the coordinates of A and B, a distance can be calculated and added as a property to the relationship

问题2

此链接节点列表的整个段可以替换为单个 - [:NEXT] - >与“距离”属性的关系,作为原始列表的相邻节点之间的所有距离的总和。如何才能有效地为数千个或更多节点做到这一点?

(A)-[:NEXT {distance: 1}]->(B)-...->(D)-[:NEXT {distance: 1}]->(E) (A)-[:NEXT {distance: 4}}->(E)

The distance between individual nodes in the first graph is added and the result assigned to the distance property in graph two, with all the intermediate nodes removed

感谢您的指导和提示。

1 个答案:

答案 0 :(得分:2)

第1部分:你正在使用lat / lon,在neo4j 3.0中有点和距离的原生支持,请确保使用latitudelongitude属性键。然后,您可以使用以下内容在关系上设置此属性:

MATCH (start:YourNodeLabel)-[r:NEXT]->(end)
SET r.distance = distance(point(start), point(end)) / 1000

第2部分:如果您知道路径的起点和终点节点,则可以通过减少关系的距离属性来创建下一个关系:

MATCH (start:YourNodeLabel {name:"A"}), (end:YourNodeLabel {name:"E"})
MATCH (start)-[r:NEXT*]->(end)
CREATE (start)-[newrel:NEXT]->(end)
SET newrel.distance = reduce(d=0.0, x IN r | d + x.distance)

请注意这一点,考虑到pathstart可能有多个end,在这种情况下,例如,如果你想找到最短的距离从开始到结束,您需要计算总距离并采用最低距离:

MATCH (start:YourNodeLabel {name:"A"}), (end:YourNodeLabel {name:"E"})
MATCH p=(start)-[:NEXT*]->(end)
WITH p, start ,end, reduce(d=0.0, x IN rels(p) | d + x.distance) as totalDistance
ORDER BY totalDistance ASC
LIMIT 1
CREATE (start)-[newRel:NEXT]->(end)
SET newRel.distance = totalDistance

如果您没有关系中的距离属性,您还可以在reduce函数中动态计算地理距离:

MATCH (start:YourNodeLabel {name:"A"}), (end:YourNodeLabel {name:"E"})
MATCH p=(start)-[:NEXT*]->(end)
WITH p, start, end, 
reduce(d=0.0, x IN range(1, size(nodes(p))-1) | d + distance(point(nodes(p)[x-1]), point(nodes(p)[x])) / 1000) as distance
ORDER BY distance ASC
LIMIT 1
CREATE (start)-[newRel:NEXT]->(end)
SET newRel.distance = distance

作为一般建议,我不会对用作快捷方式的关系使用相同的关系类型名称,可能CONNECT_TOREACH_POINT可能更适合以免干扰在其他查询中使用NEXT关系。