找到Cypher查询语言中的连续胜利

时间:2018-01-10 16:10:12

标签: neo4j cypher

Arsenal club record ordered by time

从图中我们可以看出,阿森纳连续赢了三场比赛,但是我无法写出这个问题。

1 个答案:

答案 0 :(得分:1)

这是一个应该返回阿森纳连续获胜的最大数量的查询:

MATCH (a:Club {name:'Arsenal FC'})-[r:played_with]-(:Club)
WITH ((CASE a.name WHEN r.home THEN 1 ELSE -1 END) * (TOINT(r.score[0]) - TOINT(r.score[1]))) > 0 AS win, r
ORDER BY TOINT(r.time)
RETURN REDUCE(s = {max: 0, curr: 0}, w IN COLLECT(win) |
  CASE WHEN w
    THEN {
      max: CASE WHEN s.max < s.curr + 1 THEN s.curr + 1 ELSE s.max END,
      curr: s.curr + 1}
    ELSE {max: s.max, curr: 0}
  END
  ).max AS result;

WITH子句将win变量设置为true iff阿森纳赢得特定游戏。请注意,ORDER BY子句将time属性转换为整数,因为如果字符串可能具有不同的长度,则数字字符串的排序无法正常工作(我正在不可否认,这里有点挑剔。 REDUCE函数用于计算连续获胜的最大数量。

==

最后,这里有一些建议可以改进您的数据模型。例如:

  • 看起来你的played_with关系总是从主队指向客队。如果是这样,您可以摆脱多余的homeaway属性,还可以将关系类型重命名为HOSTED,以使关系的方向更加清晰。
  • 分数和时间应存储为整数,而不是字符串。这将使您的查询更有效,更易于编写和理解。
  • 您还可以考虑将scores属性拆分为两个标量属性,例如homeScoreawayScore,这会使您的代码更加清晰。将分数存储在数组中似乎没有任何好处。

如果您进行了上述所有建议的更改,那么您只需将上述查询的开头更改为:

MATCH (a:Club {name:'Arsenal FC'})-[r:HOSTED]-(:Club)
WITH ((CASE a WHEN STARTNODE(r) THEN 1 ELSE -1 END) * (r.homeScore - r.awayScore)) > 0 AS win, r
ORDER BY r.time
...