按路径顺序对 Return 个节点进行 Cypher 查询
Cypher Query to Return Nodes in Path Order
我有一个存储有序节点集合的 neo4j graphdb(比方说 Person 节点),每个人都有一个 Talent 节点:
(p:Person)-[:HAS_TALENT]->(t:Talent)
我正在组织一场才艺表演,并且有表演顺序的时间表:
(p:Person)-[:FOLLOWS*]->(q:Person)
我可以向 return 一条代表人们执行顺序的路径编写查询,当我 return 该路径时,Person 节点将按照它们出现的顺序显示在路径中。但是,当我对 return 人们正在表演的才能进行子查询时,他们不再按路径顺序显示。
有没有办法根据节点在路径中出现的顺序对节点进行排序?我已经尝试使用 COLLECT
来获取 Person 节点列表,但我似乎无法找到一种方法来使用该集合来取回 ordered Talent 列表节点。
我当前的路径查询看起来像这样,有一个特殊的开始和结束节点,所以我知道谁是第一个和最后一个。 (我现在面前没有数据库,如果不是很抱歉,我深表歉意):
MATCH p=(s:StartNode {side:"start"})-[:FOLLOWS*1..10]->(s:StartNode {side:"end"})
RETURN p
我已经 运行 从头到尾通过许多不同的选项来检索路径,它们各有利弊,但我找不到检索 Talent 节点的方法同样的顺序。
编辑: 看来我可能过度简化了示例场景。我实际使用的数据库有从开始到结束通过 Person 节点的多条路径,在继续匹配 Talent 节点之前,我首先查询 select 从开始到结束只有一条路径。向@Dirk Horsten 道歉,他回答了我提出的问题,但不是我需要回答的问题。
因为我已经在编辑这个了,@Dave Bennett 的回答解决了我的问题,因为 unwind
函数似乎保持路径的顺序完整,以供将来的 MATCH 子句使用。
如果我在前面加一个(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)
当然你也可以 return 完整的 t
,你可以 collect(t.tId)
或任何你喜欢的
(要在装有 Neo4j 的 PC 上进行测试)
假设表演者是 Person 1..5 并且他们每个人都拥有一个才能 A..E 这样 Person 1
有 Talent A
并且 Person 5
有 Talent 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
我有一个存储有序节点集合的 neo4j graphdb(比方说 Person 节点),每个人都有一个 Talent 节点:
(p:Person)-[:HAS_TALENT]->(t:Talent)
我正在组织一场才艺表演,并且有表演顺序的时间表:
(p:Person)-[:FOLLOWS*]->(q:Person)
我可以向 return 一条代表人们执行顺序的路径编写查询,当我 return 该路径时,Person 节点将按照它们出现的顺序显示在路径中。但是,当我对 return 人们正在表演的才能进行子查询时,他们不再按路径顺序显示。
有没有办法根据节点在路径中出现的顺序对节点进行排序?我已经尝试使用 COLLECT
来获取 Person 节点列表,但我似乎无法找到一种方法来使用该集合来取回 ordered Talent 列表节点。
我当前的路径查询看起来像这样,有一个特殊的开始和结束节点,所以我知道谁是第一个和最后一个。 (我现在面前没有数据库,如果不是很抱歉,我深表歉意):
MATCH p=(s:StartNode {side:"start"})-[:FOLLOWS*1..10]->(s:StartNode {side:"end"})
RETURN p
我已经 运行 从头到尾通过许多不同的选项来检索路径,它们各有利弊,但我找不到检索 Talent 节点的方法同样的顺序。
编辑: 看来我可能过度简化了示例场景。我实际使用的数据库有从开始到结束通过 Person 节点的多条路径,在继续匹配 Talent 节点之前,我首先查询 select 从开始到结束只有一条路径。向@Dirk Horsten 道歉,他回答了我提出的问题,但不是我需要回答的问题。
因为我已经在编辑这个了,@Dave Bennett 的回答解决了我的问题,因为 unwind
函数似乎保持路径的顺序完整,以供将来的 MATCH 子句使用。
如果我在前面加一个(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)
当然你也可以 return 完整的 t
,你可以 collect(t.tId)
或任何你喜欢的
(要在装有 Neo4j 的 PC 上进行测试)
假设表演者是 Person 1..5 并且他们每个人都拥有一个才能 A..E 这样 Person 1
有 Talent A
并且 Person 5
有 Talent 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