Cypher / neo4j возвращают пути с общей начальной и конечной точкой, причем конечная точка фильтруется по количеству путей - PullRequest
0 голосов
/ 28 ноября 2018

Проблема: я хочу использовать cypher для возврата путей, где я могу указать начальную точку, и отфильтровать по количеству соединений, входящих в конечную точку для этих путей.

Некоторые фиктивные данные примера:

путь1: (a1: a) - (b1: b) - (c1: c) - (d1: d)

путь2: (a1: a) - (b2:b) - (c2: c) - (d1: d)

path3: (a1: a) - (b3: b) - (c3: c) - (d2: d)

path4: (a1: a) - (b2: b) - (c2: c) - (d3: d)

path5: (a2: a) - (b4: b) - (c4: c) - (d3: d)

Цель: я хочу вернуть все пути, которые начинаются с a1 и заканчиваются на dn, где количество отношений до dnиз путей, начинающихся с a1, составляет> 1 (или 2, или 3… в приведенном выше примере мы будем использовать> 1, но я хочу иметь возможность изменить это для реальных данных, где число отношений может быть намного выше).

В приведенном выше примере я хочу включить путь 1 и путь 2, потому что они оба начинаются с a1 и заканчиваются на d1, а количество путей, начинающихся на a1 и заканчивающихся на d1, равно 2 (то есть> 1).

пути 3 и 4 будутбыть исключенным, потому что, хотя они начинаются с a1, нет других путей, начинающихся с a1, которые заканчиваются на d2 или d3.Другими словами, d2 и d3 уникальны в контексте путей, начинающихся с a1.

путь 5 будет исключен, поскольку он не начинается с a1, даже если есть> 1 пути, которые заканчиваются на d3

Все промежуточные узлы в основном не имеют значения, кроме возможности указать свои метки во время запроса и получить узлы, которые составляют путь в конце.

Я посмотрел, но могу 'не найти ничего, что решает эту проблему в другом месте

1 Ответ

0 голосов
/ 28 ноября 2018

Ваш график

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

CREATE
  (a1:LabelA {name: 'A1'})-[:BELONGS_TO]->(b1:LabelB {name: 'B1'})-[:BELONGS_TO]->(c1:LabelC {name: 'C1'})
    -[:BELONGS_TO]->(d1:LabelD {name: 'D1'}),
  (a1)-[:BELONGS_TO]->(b2:LabelB {name: 'B2'})-[:BELONGS_TO]->(c2:LabelC {name: 'C2'})-[:BELONGS_TO]->(d1),
  (a1)-[:BELONGS_TO]->(b3:LabelB {name: 'B3'})-[:BELONGS_TO]->(c3:LabelC {name: 'C3'})
    -[:BELONGS_TO]->(d2:LabelD {name: 'D2'}),
  (c2)-[:BELONGS_TO]->(d3:LabelD {name: 'D3'}),
  (a2:LabelA {name: 'A2'})-[:BELONGS_TO]->(b4:LabelB {name: 'B4'})-[:BELONGS_TO]->(c4:LabelC {name: 'C4'})
    -[:BELONGS_TO]->(d3);

Graph

Решение

MATCH path = (:LabelA {name:'A1'})-[:BELONGS_TO*]->(endNode:LabelD) 
WITH endNode, count(endNode) AS endNodeAmount WHERE endNodeAmount > 1 
RETURN endNode.name AS endNode, endNodeAmount;

Основная идея

  • первая строка: определить шаблон для пути от A1 до Dn произвольной длины
  • вторая строка: количество для каждого конечного узла(Dn) количество вхождений и фильтр для него, цифру 1 можно заменить параметром $relationshipAmount
  • , третья строка: представить результаты

Результат

╒═════════╤═══════════════╕
│"endNode"│"endNodeAmount"│
╞═════════╪═══════════════╡
│"D1"     │2              │
└─────────┴───────────────┘


Расширение: вариант "Пути"

Решение

Если вас интересуют пути между узлом A1 и идентифицированным Dx, вы можетеположитесь на следующий запрос Cypher.

MATCH path = (startNode:LabelA {name:'A1'})-[:BELONGS_TO*]->(endNode:LabelD) 
WITH collect(path) as paths, endNode WHERE size(paths) > 1 
UNWIND paths as path RETURN path;

(С поклоном и спасибо @InverseFalcon за идею оптимизации.)

Результат

╒═══════════════════════════════════════════════╕
│"path"                                         │
╞═══════════════════════════════════════════════╡
│[{"name":"A1"},{},{"name":"B1"},{"name":"B1"},{│
│},{"name":"C1"},{"name":"C1"},{},{"name":"D1"}]│
├───────────────────────────────────────────────┤
│[{"name":"A1"},{},{"name":"B2"},{"name":"B2"},{│
│},{"name":"C2"},{"name":"C2"},{},{"name":"D1"}]│
└───────────────────────────────────────────────┘

Graph 2

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