(使用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}] - >在两个相邻节点之间。鉴于我有这样的数千个节点,你怎么能这样做呢?
问题2
此链接节点列表的整个段可以替换为单个 - [:NEXT] - >与“距离”属性的关系,作为原始列表的相邻节点之间的所有距离的总和。如何才能有效地为数千个或更多节点做到这一点?
(A)-[:NEXT {distance: 1}]->(B)-...->(D)-[:NEXT {distance: 1}]->(E)
(A)-[:NEXT {distance: 4}}->(E)
感谢您的指导和提示。
答案 0 :(得分:2)
第1部分:你正在使用lat / lon,在neo4j 3.0中有点和距离的原生支持,请确保使用latitude
和longitude
属性键。然后,您可以使用以下内容在关系上设置此属性:
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)
请注意这一点,考虑到path
到start
可能有多个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_TO
或REACH_POINT
可能更适合以免干扰在其他查询中使用NEXT
关系。