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

时间:2016-01-05 16:51:28

标签: neo4j cypher

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

(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

但是,我想知道如果没有'start'和'end'属性,是否有更好的方法来实现这一目标。我在不使用属性时遇到的问题是序列被分解,而不是我得到的一个序列:

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

是否有可能以任何方式获得完整的序列?

2 个答案:

答案 0 :(得分:3)

您可以要求last位于&#34;链的末端&#34;:

MATCH path=(:Obj {name:'O1'})<-[:OBJECT]-(:SEQ)<-[:PREV*]-(last:SEQ)
WHERE NOT (last)<-[:PREV]-(:SEQ)
RETURN path

答案 1 :(得分:1)

是的,你可以。您只需按大小按降序对结果路径进行排序,并仅返回最长的路径。

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