Учитывая следующий график:
![enter image description here](https://i.stack.imgur.com/3sl84.png)
Который можно создать с помощью следующего сценария Cypher:
CREATE
(n1:Token {content: "lonely"}),
(n2:Token {content: "island"}),
(n1)-[:PRECEDES]->(n2);
CREATE
(n1:Token {content: "the"}),
(n2:Token {content: "quick"}),
(n3:Token {content: "brown"}),
(n4:Token {content: "fox"}),
(n5:Token {content: "bear"}),
(n1)-[:PRECEDES]->(n2),
(n2)-[:PRECEDES]->(n3),
(n3)-[:PRECEDES]->(n4),
(n3)-[:PRECEDES]->(n5);
Я хочу запрос, который вернет узлы в пути от заданного корня, следуя
PRECEDES отношения в обратном направлении. Запрос должен также вернуть все
входящие отношения для данного узла, так что я могу построить подграф
в памяти позже. Тем не менее, список входящих отношений никогда не должен указывать
вне возвращенного корня.
Например, если я запрашиваю корень lonely
, я хочу получить результат:
+-----------------------------------------------------------------------+
| (:Token {content: "lonely"}) | [] |
| (:Token {content: "island"}) | [[:PRECEDES]] |
+-----------------------------------------------------------------------+
Если я запрашиваю корень the
, я хочу получить результат:
+-----------------------------------------------------------------------+
| (:Token {content: "the"}) | [] |
| (:Token {content: "quick"}) | [[:PRECEDES]] |
| (:Token {content: "brown"}) | [[:PRECEDES]] |
| (:Token {content: "fox"}) | [[:PRECEDES]] |
| (:Token {content: "bear"}) | [[:PRECEDES]] |
+-----------------------------------------------------------------------+
Если я запрашиваю корень brown
, я хочу получить следующий результат, обратите внимание, что
входящие отношения для brown
были отменены, потому что
указать за пределами подграфа.
+-----------------------------------------------------------------------+
| (:Token {content: "brown"}) | [] |
| (:Token {content: "fox"}) | [[:PRECEDES]] |
| (:Token {content: "bear"}) | [[:PRECEDES]] |
+-----------------------------------------------------------------------+
Корневой и листовой узлы всегда должны быть включены в результат.
Пока это моя попытка:
MATCH (a:Token {content: {root}})-[:PRECEDES*]->(t:Token)
WITH COLLECT(a) + COLLECT(DISTINCT t) AS nodes_
UNWIND nodes_ AS n
OPTIONAL MATCH p = (n)-[r]-()
WITH n AS n2, COLLECT(DISTINCT RELATIONSHIPS(p)) AS nestedrel
RETURN n2, REDUCE(output = [], rel in nestedrel | output + rel) AS rels
Это вроде как близко, но есть несколько проблем: использование COLLECT(a)
для
искусственно включить корень хаки, он оставляет отношения, которые
указать на корень в результате отношений, и если вы попытаетесь использовать
листовой узел как корень не будет возвращать никаких узлов вообще. (REDUCE
часть
просто сплющить список отношений на один уровень.)
[К вашему сведению, мне нужно перестроить эту древовидную структуру в памяти как
NetworkX MultiDiGraph.]