Как суммировать значение свойства типа узла, отличного от начального и конечного узла с Cypher в Neo4j - PullRequest
0 голосов
/ 14 июня 2019

У меня есть Neo4j community 3.5.5, где я построил модель графических данных с железнодорожной станцией и участками линий между станциями.Станции и линейные участки являются узлами, а связь - это связь, связывающая их.

Stations and line sections

Я хотел бы назвать начальную станцию ​​и конечную станцию ​​и подвести итог всей железнодорожной секции между ними.Я попробовал запрос Cypher ниже, но Neo4j не распознает line_section как тип узла.

match (n1:Station)-[:Connect]-(n2:Station)
where n1.Name='Station1' and n2.Name='Station3'
return sum(Line_Section.length)

Я знаю, что можно выполнить суммирование с помощью Neo4j Traversal API.Возможно ли сделать это в Cypher?

Ответы [ 2 ]

1 голос
/ 14 июня 2019

Сначала capture путь от начального узла до конечного узла в переменной, затем reduce свойство длины над ним.

MATCH path=(n1: Station { name: 'Station1' })-[:Connect]->(n2: Station { name: 'Station2' })
RETURN REDUCE (totalLength = 0, node in nodes(path) | totalLength + node.length) as totalDistance
0 голосов
/ 14 июня 2019

Предполагая, что узлы сечения линии имеют метку Line_Section, вы можете использовать шаблон отношения переменной длины , чтобы получить полный путь, понимание списка , чтобы получить списокузлы сечения линии, UNWIND , чтобы получить отдельные узлы, а затем использовать агрегацию до SUM всех длин сечения линии:

MATCH p = (n1:Station)-[:Connect*]-(n2:Station)
WHERE n1.Name='Station1' AND n2.Name='Station3'
UNWIND [n IN NODES(p) WHERE 'Line_Section' in LABELS(n)] AS ls
RETURN p, SUM(ls.length) AS distance

Или вы можетеиспользуйте REDUCE вместо UNWIND и SUM:

MATCH p = (n1:Station)-[:Connect*]-(n2:Station)
WHERE n1.Name='Station1' AND n2.Name='Station3'
RETURN p, REDUCE(s = 0, ls IN [n IN NODES(p) WHERE 'Line_Section' in LABELS(n)] |
  s + ls.length) AS distance

[ОБНОВЛЕНО]

Note: a variable-length relationship with an unbounded number of hops is expensive, and can take a long time or run out of memory.

If you only want the distance for the shortest path, then this should be faster:

MATCH
  (n1:Station { name: 'Station1' }),
  (n2:Station {name: 'Station3' }),
  p = shortestPath((n1)-[*]-(n2))
WHERE ALL(r IN RELATIONSHIPS(p) WHERE TYPE(r) = 'Connect')
RETURN p, REDUCE(s = 0, ls IN [n IN NODES(p) WHERE 'Line_Section' in LABELS(n)] |
  s + ls.length) AS distance
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...