cypher如何获得每两个节点之间的关系以及距起始节点的距离?

时间:2018-03-14 10:43:12

标签: neo4j cypher cypher-3.1

我有一些节点和关系,如A -> B ->C -> D;和B->D所以B C D是一个循环,现在我想从节点A获得所有关系和每个关系距离; 我希望结果如下:

{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}

和我的密码:

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

但这总是得到一件我不需要的东西:

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

如果有像“8”这样的双循环则结果更糟

我怎么写密码?

1 个答案:

答案 0 :(得分:1)

虽然很容易与终端节点保持距离,但是你需要获得最后一个关系以及你想要的结果,这对于Cypher来说很难(可能不可能?),因为关系可能会被多次遍历取决于图形的连通性,并且因为相同的关系将出现为不同长度的路径的最后关系。

如果你绝对需要这个,那么你可以使用APOC path expander procedures来确保每个关系只被遍历一次,所以你不会得到与结果相同的关系,但是对于不同的路径。

应该为您提供所需结果的用法示例:

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

至于纯Cypher解决方案,您可能会在高度连接的图表上出现问题,因为Cypher的扩展试图找到所有可能的路径。但是你走了。

找到所有连接节点的最短距离:

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

找到连接所有连接节点的所有关系:

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