Как я уже упоминал в своем последнем посте я пытаюсь освоиться из С заявлением в Neo4j в шифровальщике языке запросов , и я нашел другое приложение при попытке работы, какие соперники команда играла в определенные дни.
Я начал с запроса, который сгруппировал набор данных по дням и показал противников, которые игрались в этот день:
START team = node:teams('name:"Manchester United"') MATCH team-[h:home_team|away_team]-game-[:on_day]-day RETURN DISTINCT day.name, COLLECT(TRIM(REPLACE(REPLACE(game.name, "Manchester United", ""), "vs", "")))
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | day.name | opponents | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | "Sunday" | ["Liverpool","Everton","Southampton","Liverpool","Newcastle United","Chelsea","Manchester City","Swansea City","Tottenham Hotspur"] | | "Wednesday" | ["Southampton","West Ham United","Newcastle United"] | | "Monday" | ["Everton"] | | "Saturday" | ["Reading","Fulham","Wigan Athletic","Tottenham Hotspur","Stoke City","Arsenal","Queens Park Rangers","Sunderland","West Bromwich Albion","Norwich City","Reading","Aston Villa","Norwich City","Fulham","Queens Park Rangers"] | | "Tuesday" | ["Wigan Athletic"] | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 5 rows
То, как у нас есть противники, является чем-то вроде хака — название двух команд находится в свойстве «name» игрового узла, и мы удалили «Manchester United» и слово «vs», чтобы получить имя оппонента.
Я подумал, что было бы здорово, если бы мы могли разделять игры каждый день в зависимости от того, играют ли «Манчестер Юнайтед» дома или в гостях.
С большой помощью Уэса Фримена мы получили следующий запрос:
START team = node:teams('name:"Manchester United"') MATCH team-[h:home_team|away_team]-game-[:on_day]-day WITH day.name as d, game, team, h MATCH team-[:home_team|away_team]-game-[:home_team|away_team]-opp WITH d, COLLECT([type(h),opp.name]) AS games RETURN d, EXTRACT(c in FILTER(x in games: HEAD(x) = "home_team") : HEAD(TAIL(c))) AS home, EXTRACT(c in FILTER(x in games: HEAD(x) = "away_team") : HEAD(TAIL(c))) AS away
Мы используем аналогичный подход с COLLECT, как и в предыдущем посте, в котором мы имеем коллекцию кортежей, описывающих, был ли «Манчестер Юнайтед» дома или нет, и с кем они играли.
Замечательно то, что Уэс указал на то, что, поскольку в каждой игре есть только 2 команды, мы можем легко получить узел противника, потому что это единственный другой узел, который может соответствовать отношению «home_team | away_team», так как мы уже сопоставили наш команда.
Если мы выполним запрос только до последнего WITH, мы получим следующий результат:
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | d | games | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | "Sunday" | [["home_team","Liverpool"],["home_team","Everton"],["away_team","Southampton"],["away_team","Liverpool"],["away_team","Newcastle United"],["away_team","Chelsea"],["away_team","Manchester City"],["away_team","Swansea City"],["away_team","Tottenham Hotspur"]] | | "Wednesday" | [["home_team","Southampton"],["home_team","West Ham United"],["home_team","Newcastle United"]] | | "Monday" | [["away_team","Everton"]] | | "Saturday" | [["home_team","Reading"],["home_team","Fulham"],["home_team","Wigan Athletic"],["home_team","Tottenham Hotspur"],["home_team","Stoke City"],["home_team","Arsenal"],["home_team","Queens Park Rangers"],["home_team","Sunderland"],["home_team","West Bromwich Albion"],["home_team","Norwich City"],["away_team","Reading"],["away_team","Aston Villa"],["away_team","Norwich City"],["away_team","Fulham"],["away_team","Queens Park Rangers"]] | | "Tuesday" | [["away_team","Wigan Athletic"]] | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 5 rows
Затем мы используем функцию FILTER, чтобы выбрать оппонентов, с которыми «Манчестер Юнайтед» играл дома или в гостях, а затем мы используем функцию « ЭКСТРАКТ», чтобы вытащить противника из кортежа:
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | d | home | +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | "Sunday" | ["Liverpool","Everton"] | | "Wednesday" | ["Southampton","West Ham United","Newcastle United"] | | "Monday" | [] | | "Saturday" | ["Reading","Fulham","Wigan Athletic","Tottenham Hotspur","Stoke City","Arsenal","Queens Park Rangers","Sunderland","West Bromwich Albion","Norwich City"] | | "Tuesday" | [] | +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 5 rows +-----------------------------------------------------------------------------------------------------------------------------+ | d | away | +-----------------------------------------------------------------------------------------------------------------------------+ | "Sunday" | ["Southampton","Liverpool","Newcastle United","Chelsea","Manchester City","Swansea City","Tottenham Hotspur"] | | "Wednesday" | [] | | "Monday" | ["Everton"] | | "Saturday" | ["Reading","Aston Villa","Norwich City","Fulham","Queens Park Rangers"] | | "Tuesday" | ["Wigan Athletic"] | +-----------------------------------------------------------------------------------------------------------------------------+
(Я выполнил запрос дважды, чередуя две последние строки, чтобы его можно было прочитать здесь. На самом деле выездные команды были бы в столбце рядом с домашними командами)
Я подумал, что было довольно интересно, сколько игр «Манчестер Юнайтед» разыгрывает в воскресенье — я думаю, что все эти игры, вероятно, транслировались по телевидению, поэтому я думал, что они будут более равномерно распределены между домашними и выездными матчами. Добавление телевизионных совпадений, возможно, еще один слой, добавляемый на график .
Вероятно, было бы более полезно обобщить, сколько игр было сыграно каждый день дома и в гостях, а не против кого они играют, и мы можем использовать функцию REDUCE, чтобы сделать это:
START team = node:teams('name:"Manchester United"') MATCH team-[h:home_team|away_team]-game-[:on_day]-day WITH day.name as dayName, game, team, h MATCH team-[:home_team|away_team]-game-[:home_team|away_team]-opp WITH dayName, COLLECT([type(h),opp.name]) AS games RETURN dayName, REDUCE(homeGames=0, game in EXTRACT(c in FILTER(x in games: head(x) = "home_team") : HEAD(TAIL(c))) : homeGames + 1) as home, REDUCE(awayGames=0, game in EXTRACT(c in FILTER(x in games: head(x) = "away_team") : HEAD(TAIL(c))) : awayGames + 1) as away, REDUCE(totalGames=0, game in games : totalGames + 1) as total
+-----------------------------------+ | dayName | home | away | total | +-----------------------------------+ | "Sunday" | 2 | 7 | 9 | | "Wednesday" | 3 | 0 | 3 | | "Monday" | 0 | 1 | 1 | | "Saturday" | 10 | 5 | 15 | | "Tuesday" | 0 | 1 | 1 | +-----------------------------------+ 5 rows
Альтернативный способ написания начального запроса — следующий, который Майкл Хангер предложил в теме:
START team = node:teams('name:"Manchester United"') MATCH p=team-[:home_team|away_team]-game-[:home_team|away_team]-(), game-[:on_day]-day WITH day.name as dayName, COLLECT([LAST(p), HEAD(RELS(p))]) AS opponents WITH dayName, EXTRACT(y in FILTER(x in opponents: TYPE(HEAD(TAIL(x))) = "home_team") : HEAD(y)) AS home, EXTRACT(y in FILTER(x in opponents : TYPE(HEAD(TAIL(x))) = "away_team") : HEAD(y)) AS away RETURN dayName, EXTRACT(team in home: team.name) AS homeOpponents, EXTRACT(team in away: team.name) AS awayOpponents ORDER BY dayName
Здесь мы используем немного другой подход, в котором мы используем функции, которые мы можем применить к соответствующему пути. Мы создаем коллекцию кортежей, где LAST (p) соответствует узлу противника, а HEAD (RELS (p)) соответствует отношению «home_team» или «away_team» соответственно.
Затем мы фильтруем коллекцию, чтобы найти время, в которое мы играли дома и в гостях. Это делается путем получения второго значения из кортежа и последующего вызова для него TYPE, который либо возвращает «home_team» или «away_team». Затем мы извлекаем первое значение из кортежа, который является узлом оппонента.
В последней части запроса мы извлекаем имя из узлов противника.