Ваш запрос возвращает текущий t.total
результат для узла вместо общего итогового значения.И, похоже, неправильно вычисляется расстояние для первого узла в сегменте (первый узел должен иметь расстояние 0).Это также очень неэффективно.Например, он не беспокоится об использовании отношения defines
.В запросе neo4j жизненно важно использовать силу взаимосвязей, чтобы избежать сканирования большого количества не относящихся к делу данных.
Кроме того, нет никакого упоминания о конкретном "городе".Ваш запрос для всех Entity
узлов.Если ваша БД содержит только Entity
узлов для одного города, то это нормально.В противном случае вам нужно будет изменить запрос так, чтобы он совпадал только с Entity
узлами для определенного города.
Следующий запрос может сделать то, что вы хотите (исходя из того, что я почерпнул из вашего вопроса, и предполагая, что ваша БДтолько данные для одного города), используя отношение defines
для эффективного сопоставления узла start
для каждого сегмента Entity
и использование этого узла start
для эффективного поиска интересующих узлов connected
:
MATCH (entity:Entity {type:'road'})-[:defines]->(start)
MATCH p=(start)-[:connected* {entity_id:entity.id}]->(end)
WHERE NOT EXISTS((end)-[:connected {entity_id:entity.id}]->())
SET entity.lng = 0
SET entity.p = point({longitude:toFloat(start.lon), latitude: toFloat(start.lat)})
WITH entity, p
UNWIND TAIL(NODES(p)) AS nd
WITH point({longitude:toFloat(nd.lon), latitude: toFloat(nd.lat)}) as pt, entity
SET entity.lng = entity.lng + distance(entity.p, pt)
SET entity.p = pt
RETURN SUM(entity.lng) AS total
Функция агрегирования SUM()
используется для возврата суммы lng
для всех сущностей.Узел t
не нужен.Предложение WHERE
соответствует только путям, которые содержат полные сегменты.Этот запрос также инициализирует entity.p
для point
узла start
и UNWINDS
узлов после узла start
.
Если существует много узлов Entity
с type
значения, отличные от «road», вы также можете создать index для :Entity(type)
.