问题
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