Нахождение самых последовательных побед в регби - PullRequest
0 голосов
/ 27 ноября 2018

Предположим, что результаты лиги регби даются такими данными:

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 голосов
/ 27 ноября 2018

[ОБНОВЛЕНО]

Если мы изменим формат ваших 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

Затем мы можем импортировать данные, подобные этим (вместо 1007 * используется MERGE, чтобы избежать создания дублирующих узлов 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_TEAM и AWAY_TEAM.

Предложение WITH вычисляет статистику побед для каждой игры, сыгранной каждой командой, и упорядочивает их по date и round.

Поскольку в предложении RETURN используется агрегирующая функция COLLECT (в функции REDUCE ), в качестве агрегации grouping key используется переменная t.Это заставляет функцию REDUCE обрабатывать всю упорядоченную статистику побед для одной команды за раз .

Функция REDUCE accumulator, s - это карта с 3 свойствами:

  • max - это число максимум к настоящему времени обнаружены последовательные выигрыши.
  • c - количество последовательных побед для текущей последовательности побед.
  • prev - статистика выигрышей для предыдущая игра.

Поскольку у Cypher нет предложения IF, предложение CASE используется для логического ветвления.(Примечание: предложение CASE может только возвращать значение - оно не может выполнять какие-либо операции чтения / записи в БД).Различные пункты CASE в этом запросе служат для надлежащего обновления accumulator при переборе каждой игры по порядку.

Когда функция REDUCE выполняется со всеми играми для команды,предложение RETURN принимает значение max возвращенной карты и присваивает его переменной maxConsecutiveWins.

Последнее предложение ORDER BY сортирует все значения maxConsecutiveWins в порядке убывания, иПредложение LIMIT только позволяет вернуть первый (тот, который имеет наибольшее значение) вместе с соответствующей командой.

Результат с данными, приведенными выше, будет:

╒══════════════╤════════════════════╕
│"t"           │"maxConsecutiveWins"│
╞══════════════╪════════════════════╡
│{"name":"ABC"}│2                   │
└──────────────┴────────────────────┘

ПРИМЕЧАНИЕ. Учитывая сложность предложений CASE, вы должны протестировать приведенный выше запрос со всеми возможными крайними случаями, если вы действительно планируете его использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...