Match on shortest distance with aggregation function min() in Cypher

和自甴很熟 提交于 2019-12-11 16:28:20

问题


I have Station nodes, and Neighborhood nodes. They both have a location attribute which is of type point of the spatial data type.

I need to create a relationship between the nodes (a Station belongs to the closest neighborhood). Therefore, I should only get one row per station. However, my query gives back all combinations as a result.

MATCH (n:Neighborhood),(s:Station)
WITH n, s, min(distance(n.centerLocation, s.point)) AS shortest
WHERE distance(n.centerLocation, s.point) = shortest
RETURN s.stationId, n.name, shortest
ORDER BY s.stationId

回答1:


[UPDATED]

Your aggregation is using both n and s as the grouping keys, instead of just s.

This should work for you:

MATCH (n:Neighborhood), (s:Station)
WITH n, s, distance(n.centerLocation, s.point) AS dist
ORDER BY dist
RETURN s.stationId, COLLECT(n)[0].name AS name, COLLECT(dist)[0] AS shortest
ORDER BY s.stationId

Note that this query is going to be slow (and possibly run out of memory) if you have a lot of neighborhoods and stations, since it will have to evaluate every possible combination of neighborhood and station.

As a potential workaround to that, you could create a relatively small number of Region nodes and relate every Station and Neighborhood to a particular Region. Once that is done, you can reduce the number of combinations that need to be evaluated. For example:

MATCH (n:Neighborhood)-[:IN_REGION]->()<-[:IN_REGION]-(s:Station)
WITH n, s, distance(n.centerLocation, s.point) AS dist
ORDER BY dist
RETURN s.stationId, COLLECT(n)[0].name AS name, COLLECT(dist)[0] AS shortest
ORDER BY s.stationId

For better results, you could also put a Station or Neighborhood into multiple regions if its distances to those regions' centerpoints only differ by some threshold.



来源:https://stackoverflow.com/questions/58419391/match-on-shortest-distance-with-aggregation-function-min-in-cypher

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!