Похоже, вы могли бы пропустить функцию агрегирования и просто упорядочить расстояние и взять верх:
MATCH (a { agency: "Bus", stop_id: "1234" }), (b { agency: "Train" })
WITH distance(a.location, b.location) AS dist, a, b
ORDER BY dist DESC
LIMIT 1
RETURN a.stop_id as orig_stop_id, b.stop_id AS dest_stop_id, dist
Как уже упоминали другие, вы действительно должны использовать здесь метки (в противном случае это все сканирование узлов, чтобы найти ваши начальные точки, это, вероятно, является основным узким местом производительности вашего запроса), и у вас есть индексы, поэтому вы используете поиск индекса для a и b.
EDIT
Если вам нужен ближайший, когда у вас есть несколько начальных узлов, вы можете взять заголовок собранных элементов следующим образом:
MATCH (a { agency: "Bus", stop_id: "1234" }), (b { agency: "Train" })
WITH distance(a.location, b.location) AS dist, a, b
ORDER BY dist DESC
WITH a, head(collect(b {.stop_id, dist})) as b
RETURN a.stop_id as orig_stop_id, b.stop_id AS dest_stop_id, b.dist as dist
Нам нужно включить dist
в проекцию карты из b
, в противном случае он будет использоваться как ключ группировки вместе с a
.
В качестве альтернативы вы можете просто собрать b
вместо проекции карты, а затем пересчитать с помощью функции distance()
для оставшейся строки.