Получить дерево с Neo4j

Учитывая лес деревьев на REST-сервере Neo4j, я пытаюсь вернуть одно дерево с заданной корневой вершиной.

Поскольку каждое дерево достаточно велико, мне необходим дедуплицированный список всех вершин и ребер, чтобы можно было восстановить полное дерево на стороне клиента.

Я пробовал несколько комбинаций вокруг MATCH (r:root)-[*]->() но они возвращают любой путь, начиная с корня, таким образом, с большим количеством дубликатов:

MATCH p = (r:root)-[*]->(x)
RETURN nodes(p) AS Vertices, rels(p) AS Edges";

это возвращает каждый путь следующим образом, повторяя каждый узел каждый раз:

a->b
a->b->c
a->b->c->d

так далее...

Вместо этого мне нужен результат, имеющий

{
    Vertices: [a, b, c, d],
    Edges: [[a, b], [b, c], [c, d]]
}

Я использую Node.js с Seraph, если это уместно, но я не строго привязан к этой библиотеке.

1 ответ

Решение

Итак, во-первых, вы можете добавить WHERE предложение, чтобы убедиться, что ваш путь всегда заканчивается листом:

MATCH p = (r:root)-[*]->(x)
WHERE NOT(x-->())
RETURN nodes(p) AS Vertices, rels(p) AS Edges";

Во-вторых, если вы хотите получить все узлы и отношения за один раз, вам может потребоваться выполнить два запроса:

MATCH p = (r:root)-[*]->(x)
WHERE NOT(x-->())
UNWIND nodes(p) AS Vertex
RETURN DISTINCT Vertex;

MATCH p = (r:root)-[*]->(x)
WHERE NOT(x-->())
UNWIND rels(p) AS Edge
RETURN DISTINCT startNode(Edge), endNode(Edge);

Обновление (Майкл)

MATCH p = (r:root)-[*]->(x)
WHERE NOT(x-->())
UNWIND nodes(p) AS Vertex
WITH collect(DISTINCT Vertex) as nodes, p
UNWIND rels(p) AS Edge
RETURN nodes, collect(distinct Edge) as rels

Обновление 2 (Майкл)

Я нашел еще более компактный способ

MATCH p = (:root)-[r*]->(x)
RETURN collect(DISTINCT id(x)) as nodes, [r in collect(distinct last(r)) | [id(startNode(r)),id(endNode(r))]] as rels

Если вы также хотите включить корневой узел, используйте *0..

Другие вопросы по тегам