[ОБНОВЛЕНО]
Если мы изменим формат ваших 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
, вы должны протестировать приведенный выше запрос со всеми возможными крайними случаями, если вы действительно планируете его использовать.