Cypher查询以路径顺序返回节点

时间:2015-01-19 20:16:21

标签: neo4j cypher

我有一个neo4j graphdb存储有序的节点集合(让我们说是Person节点),每个人都有一个Talent节点:

(p:Person)-[:HAS_TALENT]->(t:Talent)

我正在组织一场才艺表演,并制定人们将要执行的顺序表:

(p:Person)-[:FOLLOWS*]->(q:Person)

我可以编写一个查询来返回一个表示人们执行顺序的路径,当我返回该路径时,Person节点按照它们出现在路径中的顺序显示。但是,当我执行子查询以返回人们正在执行的人才时,他们不再按路径排序。

有没有办法根据节点在路径中出现的顺序对节点进行排序?我已尝试使用COLLECT获取Person节点列表,但我似乎无法找到一种方法来使用该集合来获取有序列表人才节点。

我当前的路径查询看起来像这样,有一个特殊的开始和结束节点,所以我知道谁是第一个和最后一个。 (我现在没有把DB放在我面前,所以如果它没有现场就道歉了):

MATCH p=(s:StartNode {side:"start"})-[:FOLLOWS*1..10]->(s:StartNode {side:"end"}) RETURN p

我已经通过很多不同的选项来检索从开始到结束的路径,并且它们各有利弊,但是我无法找到一种方法来检索相同的Talent节点顺序。


编辑:似乎我可能过度简化了我的示例方案。我实际使用的数据库从头到尾通过Person节点有多条路径,我有一个查询,首先从头到尾选择一条路径,然后继续前进以匹配Talent节点。向@Dirk Horsten道歉,他回答了我问的问题,但没有回答我需要回答的问题。

由于我已经编辑了这个,@ Dave Bennett的答案解决了我的问题,因为unwind函数似乎保持了路径的顺序,以便将来的MATCH条款保持不变。 / p>

2 个答案:

答案 0 :(得分:3)

假设表演者是人1 ... 5并且他们各自拥有一个人才A..E,Person 1Talent APerson 5Talent E。才艺表演以人1开始,以人5结束。

//match all of the possible show paths where the show starts
// with the first performer 
match show=(:Person {name:'Person 1'})<-[:FOLLOWS*]-(:Person) 
//
// pass on the performers and the number of performers
// as identifiers with the WITH clause
with nodes(show) as performers, length(show) as num
//
// order the possible shows in descending order by number of performers
order by num desc
//
// limit the list to the show with the most performances
limit 1
//
// unwind the performers collection as individual performer
unwind performers as p
//
// match the talent that matches the performers
match p-[:HAS_TALENT]->(t:Talent)
//
// return the name of the performer and their talent
return p.name, t.name

答案 1 :(得分:1)

如果我在前面添加一个(show)节点

create (s:show{date:'2014-01-31'})
create  (s)<-[:STARTS]-(p1:person{pId:1})-[:HAS_TALENT]->(:talent{tId:1})
create (p1)<-[:FOLLOWS]-(p2:person{pId:2})-[:HAS_TALENT]->(:talent{tId:2})
create (p2)<-[:FOLLOWS]-(p3:person{pId:3})-[:HAS_TALENT]->(:talent{tId:3})
create (p3)<-[:FOLLOWS]-(p4:person{pId:4})-[:HAS_TALENT]->(:talent{tId:4})
create (p4)<-[:FOLLOWS]-(p5:person{pId:5})-[:HAS_TALENT]->(:talent{tId:5})

然后这应该做的工作:

match spt=(s:show{date:'2014-01-31'})<-[:STARTS|FOLLOWS *]-(p:person)-[:HAS_TALENT]->(t:talent) 
return p.id as performer,t.tId as act order by length(spt)

对于cource,你也可以返回完整的t,你可以collect(t.tId)或任何你喜欢的 (在使用Neo4j的PC上进行测试)