Запрос на возврат подграфа и всех внутренних связей - PullRequest
0 голосов
/ 10 мая 2018

Учитывая следующий график:

enter image description here

Который можно создать с помощью следующего сценария 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.]

1 Ответ

0 голосов
/ 10 мая 2018

Поскольку вы пытаетесь восстановить подграф в памяти позже, вы можете использовать процедуру APOC apoc.convert.toTree и возвращать древовидную структуру напрямую, без необходимости преобразований.Таким образом, вы можете выполнять запросы как:

match p = (:Token {content: "the"})-[:PRECEDES*]->(end:Token)
where not (end)-[:PRECEDES]->()
call apoc.convert.toTree([p]) yield value
return value
...