Выполнение фильтрации по совокупному свойству отношения - PullRequest
0 голосов
/ 01 марта 2020

Я пытаюсь получить все вершины до определенного максимального совокупного веса (расстояния) от указанного c узла. Запрос

MATCH route = (p1:ReferencePlace) - [roadlist:EROAD*..5] - (p2:ReferencePlace)
WITH p1, p2, route, roadlist, 
    REDUCE(sum=0.0, road in roadlist | sum + toFloat(road.distance)) as totaldistance
WHERE totaldistance < 300
AND p1.name = "Paris"
RETURN p1, p2, totaldistance

дает правильный вывод. Здесь используется пример данных E-road, импортированных как здесь . Возвращает все места, которые находятся менее чем в 300 км от Парижа.

Проблема в том, что это работает только для ограниченного количества прыжков EROAD*..5]. Для EROAD*] оно «зависает» (я не знаю, закончится ли оно в течение любого разумного промежутка времени). Это связано с тем, что Neo4j сначала находит все возможные маршруты, а затем фильтрует их. Поэтому имеет смысл, что число маршрутов становится невероятно большим даже для такого маленького графа, как этот.

Теоретически было бы несложно реализовать алгоритм BFS с нуля, который просто собирает все соответствующие вершины, пока До тех пор, пока кумулятивное расстояние меньше порога, и только посещает соответствующие. Но мне интересно, есть ли способ сделать это в Neo4j.

1 Ответ

0 голосов
/ 09 марта 2020

Проблема может заключаться в циклах на графике, как предполагалось здесь .

В итоге я использовал алгоритм algo.shortestPath.deltaStepping.stream

PROFILE MATCH (start:ReferencePlace {name:'Paris'})
CALL algo.shortestPath.deltaStepping.stream(start, 'distance', 3.0, {relationshipQuery: 'EROAD'})
YIELD nodeId, distance
WHERE distance <= 800
RETURN algo.asNode(nodeId) AS destination, distance

Это, похоже, делает что я хочу, хотя концептуально это не прямой подход к моей проблеме. Посмотрим, как оно масштабируется для больших графиков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...