Все допустимые пути через граф с Cypher - PullRequest
0 голосов
/ 17 декабря 2018

Я пытаюсь написать запрос, который, как я подозреваю, довольно прост, но не может найти правильный подход.У меня есть данные организационной структуры в графической модели Neo4J.Он состоит из узлов (команд) org_unit и отношений BELONGS_TO.Каждое отношение имеет дату начала и окончания, чтобы определить срок действия этого отношения.Я хочу вернуть все пути через график, которые действительны на основе дат.Пути могут быть разной длины

Кажется, для этого требуются фильтрующие отношения, поэтому «более высокие» отношения соответствуют периоду действия «более низкого» (я иду снизу вверх).путь к достижению результата:

MATCH (a:Org_unit)-[r1:BELONGS_TO]->(b:Org_unit)
MATCH (c:Org_unit)-[r2:BELONGS_TO]->(d:Org_unit)
WHERE r1.endda_epoch > r2.begda_epoch 
AND r1.begda_epoch <= r2.endda_epoch 
AND b=c
RETURN a,b,c,d

Однако я действительно хочу вернуть все полные пути.Я думал, что смогу использовать одну из функций apoc.path.expand, но я думаю, что мне нужно будет отфильтровать отношения на основе атрибутов - и я не вижу, как это сделать

Спасибо

Адам

1 Ответ

0 голосов
/ 17 декабря 2018

Пример данных

Для простоты возможных дальнейших ответов и решений отмечу мое утверждение создания графика:

CREATE
  (a:OrgUnit {name: 'A'})
    <-[:BELONGS_TO {beginDate: date('2019-01-01'), endDate: date('2019-12-31')}]-(b1:OrgUnit {name: 'B1'}),
  (a)<-[:BELONGS_TO {beginDate: date('2000-01-01'), endDate: date('2019-12-31')}]-(b2:OrgUnit {name: 'B2'}),
  (a)<-[:BELONGS_TO {beginDate: date('2010-01-01'), endDate: date('2019-12-31')}]-(b3:OrgUnit {name: 'B3'}),
  (b2)<-[:BELONGS_TO {beginDate: date('2010-01-01'), endDate: date('2019-12-31')}]-(c1:OrgUnit {name: 'C1'}),
  (b2)<-[:BELONGS_TO {beginDate: date('2015-01-01'), endDate: date('2019-12-31')}]-(c2:OrgUnit {name: 'C2'}),
  (b2)<-[:BELONGS_TO {beginDate: date('2018-01-01'), endDate: date('2019-12-31')}]-(c3:OrgUnit {name: 'C3'}),
  (b3)<-[:BELONGS_TO {beginDate: date('2010-01-01'), endDate: date('2019-12-31')}]-(c4:OrgUnit {name: 'C4'}),
  (b3)<-[:BELONGS_TO {beginDate: date('2020-01-01'), endDate: date('2021-12-31')}]-(c5:OrgUnit {name: 'C5'}),
  (c4)<-[:BELONGS_TO {beginDate: date('2019-01-01'), endDate: date('2019-12-31')}]-(d1:OrgUnit {name: 'D1'});

initial situation

Решение

MATCH path = (root:OrgUnit {name: 'A'})<-[*..10]-(:OrgUnit)
WITH path WHERE 
  ALL(x IN relationships(path) WHERE x.beginDate <= $startDate) AND
  ALL(x IN relationships(path) WHERE x.endDate >= $endDate)
RETURN path;

Используемые параметры:

  • $startDate = date('2018-01-01')
  • $endDate = date('2019-01-01')

Объяснение:

  • строка 1: сопоставить все возможные пути от корня OrgUnit (CEO) до каждого OrgUnit, предполагая максимальныйглубина организации равна 10
  • строка 3: отфильтровать те пути, где не все отношения соответствуют нашему $startDate параметру
  • строка 4: отфильтровать те пути, где не все отношения соответствуют нашему$endDate параметр
  • строка 5: рендеринг результирующих путей

Результат

resulting graph

The OrgUnit s B1, C5 и D1 опущены, поскольку они действительны только для "2019-01-01", "2020-01-01" и "2019-01-01".

Примечание

Neo4j не фокусируется на поиске и фильтрации свойства отношения .Моделирование этих атрибутов как узла или свойства узла значительно более производительно, особенно для больших графов.

...