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

使用Cypher从Neo4j Graph数据库的节点序列中获取完整路径

  •  1
  • arie  · 技术社区  · 10 年前

    我存储的是一个节点序列,其中一个节点与序列中的前一个节点以及表示“对象”的另一个节点相关。例如,我可能有这样的序列:

    (S1)<-[r]-(S2)<-[r]-(S3)<-[r]-(S4)
    

    然后,序列中的每个节点与另一个节点相关,例如:

    (S1)-[r]->(O1)
    (S2)-[r]->(O2)
    (S3)-[r]->(O1)
    (S4)-[r]->(O3)
    

    在该示例中,S1和S3都与O1相关。

    我想实现的是将起点指定为“O1”,并能够在上面的示例中获得从S1到S4的完整路径。

    我能够通过在S1中添加一个名为“start”的属性和在S4中添加另一个名“end”的属性来实现这一点,以表示序列的开始和结束,并使用此查询仅获得完整的序列:

    MATCH (O:Obj{name:'O1'}), 
    path=(O)<-[:OBJECT]-(first:SEQ)<-[:PREV*]-(last:SEQ) 
    WHERE has(first.start) 
    AND has(last.end) 
    return path
    

    然而,我想知道,如果没有“开始”和“结束”属性,是否有更好的方法来实现这一点。我在不使用属性时遇到的问题是序列被分解,因此我得到的不是一个序列:

    (S1)<-[r]-(S2)
    (S1)<-[r]-(S2)<-[r]-(S3)
    (S1)<-[r]-(S2)<-[r]-(S3)<-[r]-(S4)
    (S3)<-[r]-(S4)
    

    有没有可能只得到完整的序列?

    2 回复  |  直到 10 年前
        1
  •  4
  •   cybersam    10 年前

    你可以要求 last 处于“链条末端”:

    MATCH path=(:Obj {name:'O1'})<-[:OBJECT]-(:SEQ)<-[:PREV*]-(last:SEQ)
    WHERE NOT (last)<-[:PREV]-(:SEQ)
    RETURN path
    
        2
  •  1
  •   Dave Bennett    10 年前

    是的,你可以。您只需要按大小降序排列生成的路径,并只返回最长的路径。

    match p=(:Obj {name:'O1'})<-[:REL]-(:SEQ)<-[:PREV*]-(:SEQ)
    with p, size(nodes(p)) as seq_length
    order by seq_length desc
    limit 1
    return tail(nodes(p))