cypher how get relation between every two node and

2019-08-25 11:56发布

I have some nodes and relation like A -> B ->C -> D; andB->DSo the B C D is a loop, now I want get all relations and each relation distance from node A; I expect result like:

{startNode: A, endNode: B, rel:FRIEND, distanceFromAtoEndnode: 1},
{startNode: B, endNode: C, rel:FRIEND, distanceFromAtoEndnode: 2},
{startNode: C, endNode: D, rel:FRIEND, distanceFromAtoEndnode: 3},
{startNode: B, endNode: D, rel:FRIEND, distanceFromAtoEndnode: 2}

and my cypher:

match p=(n:Person {name:"A"})-[r*1..9]-(m:Person) return last(r) as rel,length(p) as distanceFromAtoEndnode 

but this always get one more item I donot need:

{startNode: D, endNode: C, rel:FRIEND, distanceFromAtoEndnode: 3},

and if there are double loop like "8" then the result is worse

how can I write the cypher?

1条回答
我欲成王,谁敢阻挡
2楼-- · 2019-08-25 12:35

While it's easy enough to get distance to end nodes, your requirement to get the last relationship, with the results you want, will be tough (maybe impossible?) to get with just Cypher, since since relationships may be traversed multiple times depending on the connectedness of the graph, and since the same relationships will occur as the last relationship of paths of differing lengths.

If you absolutely need this, then you can use APOC path expander procedures to ensure that each relationship is only ever traversed once, so you won't get the same relationship as a result but for a different path.

An example of usage that should give you the results you want:

MATCH (n:Person {name:"A"})
CALL apoc.path.expandConfig(n, {uniqueness:'RELATIONSHIP_GLOBAL', minLevel:1, maxLevel:9, labelFilter:'>Person'}) YIELD path
WITH last(relationships(path)) as rel, length(path) as distanceFromAtoEndnode
RETURN rel {startNode:startNode(rel).name, endNode:endNode(rel).name, rel:type(rel)} as rel, distanceFromAtoEndnode

As for pure Cypher solutions, you may get hangs on highly connected graphs, since Cypher's expansion tries to find all possible paths. But here you go.

To find shortest distance for all connected nodes:

MATCH path=(:Person {name:"A"})-[*1..9]-(other:Person)
RETURN other, min(length(path)) as shortestDistance

And to find all relationships connecting all connected nodes:

MATCH path=(:Person {name:"A"})-[*1..9]-(:Person)
WITH distinct last(relationships(path)) as rel
RETURN rel {startNode:startNode(rel).name, endNode:endNode(rel).name, rel:type(rel)} as rel
查看更多
登录 后发表回答