寻找橄榄球联赛中最连续的胜利

时间:2018-11-27 18:37:44

标签: neo4j

假设橄榄球联赛的结果是通过这种数据得出的:

Date, Round, Home Team, Visitor Team, Result
18/10/2018, 1, ABC, XYZ, 30-20
18/10/2018, 1, PQR, ABC, 13-12

有人可以阐明如何对上述数据进行建模,以找出连续获胜次数最多的球队吗?

1 个答案:

答案 0 :(得分:1)

[已更新]

如果我们更改了CSV数据的格式以使其更容易导入(通过修剪多余的空白并更改为更标准的日期格式),则是这样(进行了一些额外的更改以使示例更加有趣):

Date,Round,Home Team,Visitor Team,Result
2018-10-18,1,ABC,XYZ,30-20
2018-10-18,2,ABC,PQR,28-12
2018-10-19,1,PQR,ABC,13-12

然后,我们可以像这样导入数据(使用MERGE代替CREATE,以避免创建重复的Team节点):

LOAD CSV WITH HEADERS FROM 'file:///data.csv' AS row
WITH row, SPLIT(row.Result, '-') AS scores
MERGE (h:Team {name: row.`Home Team`})
MERGE (v:Team {name: row.`Visitor Team`})
CREATE (h)<-[:HOME_TEAM {score: scores[0]}]-(g:Game {date: DATE(row.Date), round: row.Round})-[:AWAY_TEAM {score: scores[1]}]->(v)

我们可以使用此查询返回连续获胜次数最多的球队:

MATCH (t:Team)<-[r]-(g:Game)-[r2]->(t2)
WITH t, r.score > r2.score AS isWin ORDER BY g.date, g.round
RETURN t, REDUCE(s = {max: 0, c: 0, prev:false}, w IN COLLECT(isWin) |
  CASE WHEN w
    THEN {
      c: CASE WHEN s.prev THEN s.c+1 ELSE 1 END,
      max: CASE WHEN s.max <= s.c
             THEN CASE WHEN s.prev
               THEN s.c+1
               ELSE CASE WHEN s.max = 0 THEN 1 ELSE s.max END END
             ELSE s.max END,
      prev: w}
    ELSE {c: 0, max: s.max, prev: w} END).max AS maxConsecutiveWins
ORDER BY maxConsecutiveWins DESC
LIMIT 1;

MATCH模式未指定任何关系类型,因此r将同时匹配HOME_TEAMAWAY_TEAM关系。

WITH子句计算每个团队参加的每场比赛的获胜统计数据,并按dateround对其进行排序。

由于RETURN子句使用aggregating function COLLECT(在REDUCE函数内),因此t变量用作聚合{{1} }。这导致grouping key函数一次处理一个团队的所有有序获胜统计信息。

REDUCE函数的REDUCEaccumulator是具有3个属性的地图:

  • s是迄今为止发现的最大连续获胜次数。
  • max当前获胜顺序的连续获胜次数。
  • c上一个游戏的获胜统计数据。

由于Cypher没有prev子句,因此IF子句用于逻辑分支。 (注意:CASE子句只能返回一个值-它不能在数据库上执行任何读/写操作)。此查询中的各种CASE子句用于在依次迭代每个游戏的同时适当地更新CASE的目的。

在团队的所有比赛中完成accumulator函数后,REDUCE子句将获取返回地图的RETURN值并将其分配给max变量。

最后一个maxConsecutiveWins子句按降序对所有ORDER BY值进行排序,而maxConsecutiveWins子句只允许返回第一个(值最大的子句)以及与它的相应团队。

使用上述数据的结果将是:

LIMIT

注意:考虑到╒══════════════╤════════════════════╕ │"t" │"maxConsecutiveWins"│ ╞══════════════╪════════════════════╡ │{"name":"ABC"}│2 │ └──────────────┴────────────────────┘ 子句的复杂性,如果您打算实际使用它,则应在所有可能的边缘情况下测试上述查询。