代码之家  ›  专栏  ›  技术社区  ›  WesleyHsiung

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

  •  0
  • WesleyHsiung  · 技术社区  · 8 年前

    我有一些节点和关系,比如 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 回复  |  直到 8 年前
        1
  •  3
  •   InverseFalcon    8 年前

    虽然很容易获得到末端节点的距离,但要获得最后一个关系以及想要的结果,将很难(可能不可能?)由于关系可能会被多次遍历,这取决于图的连通性,并且由于相同的关系将作为不同长度路径的最后一个关系出现。

    如果您确实需要这个,那么您可以使用 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
    
    推荐文章