Fetch a tree with Neo4j

≡放荡痞女 提交于 2019-12-24 03:09:29

问题


Given a forest of trees in a Neo4j REST server, I`m trying to return a single tree given the root vertex.

Being each tree quite large, I need a de-duplicated list of all vertices and edges in order to be able to reconstruct the full tree on the client side.

I tried multiple combinations around MATCH (r:root)-[*]->() but they return any path starting from the root, thus with lots of duplicates:

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

this returns each and every path as follows, repeating each node every time:

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

etc...

Instead, I need a result having

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

I'm using Node.js with Seraph, if relevant, but I`m not strictly bound to that library.


回答1:


So first off, you might want to add a WHERE clause to make sure that your path is always ending with a leaf:

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

So secondly, if you want to get all of the nodes and relationships in one go, you may need to execute two queries:

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);

Update (Michael)

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

Update2 (Michael)

I found an even more compact way

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

If you also want to include the root node, use *0..



来源:https://stackoverflow.com/questions/30940411/fetch-a-tree-with-neo4j

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!