Я оглядывался назад на некоторые запросы Cypher, которые я написал ранее в этом году к своему футбольному набору данных, чтобы найти некоторые примеры того, как составления списков могут быть полезны, и я наткнулся на этот запрос, который используется для определения, какие команды были наиболее плохими. вел себя с точки зрения накопления красных и желтых карточек:
START team = node:teams('name:*') MATCH team<-[:for]-like_this<-[:started|as_sub]-player-[r?:sent_off_in|booked_in]->game<-[:in]-like_this WITH team, COLLECT(r) AS cards WITH team, FILTER(x IN cards: TYPE(x) = "sent_off_in") AS reds, FILTER(x IN cards: TYPE(x) = "booked_in") AS yellows RETURN team.name, LENGTH(reds) AS redCards, LENGTH(yellows) AS yellowCards ORDER BY (yellowCards*1 + redCards*3) DESC
Мы начинаем с того, что собираем все команды, выясняем, какие игроки играли в эту игру, а затем выясняем, кто был забронирован или отослан, прежде чем разделять желтые / красные карточки на их собственные соответствующие коллекции. Наконец, мы назначаем 3 очка за красную карточку и 1 очко за желтую карточку и назначаем команды на основании этого.
==> +-------------------------------------------------+ ==> | team.name | redCards | yellowCards | ==> +-------------------------------------------------+ ==> | "Stoke City" | 4 | 81 | ==> | "Newcastle United" | 4 | 74 | ==> | "Aston Villa" | 3 | 74 | ==> | "West Ham United" | 1 | 74 | ==> | "West Bromwich Albion" | 4 | 63 | ==> | "Sunderland" | 3 | 63 | ==> | "Wigan Athletic" | 2 | 66 | ==> | "Manchester City" | 3 | 62 | ==> | "Everton" | 3 | 62 | ==> | "Queens Park Rangers" | 3 | 60 | ==> | "Swansea City" | 2 | 59 | ==> | "Norwich City" | 1 | 60 | ==> | "Chelsea" | 3 | 53 | ==> | "Liverpool" | 2 | 54 | ==> | "Manchester United" | 1 | 57 | ==> | "Tottenham Hotspur" | 2 | 54 | ==> | "Arsenal" | 5 | 44 | ==> | "Fulham" | 3 | 48 | ==> | "Southampton" | 2 | 44 | ==> | "Reading" | 1 | 45 | ==> +-------------------------------------------------+ ==> 20 rows
К сожалению, если мы выполним этот запрос в базе данных 2.0.0-M05 neo4j, мы получим следующую ошибку:
==> SyntaxException: Invalid input '(': expected an identifier character, whitespace, NodeLabel, '.', '[', node labels, "=~", IN, IS, '*', '/', '%', '^', '+', '-', '<', '>', "<=", ">=", '=', "<>", "!=", AND, XOR, OR, WHERE, ')' or ',' (line 1, column 207) ==> "START team = node:teams('name:*') MATCH team<-[:for]-like_this<-[:started|as_sub]-player-[r?:sent_off_in|booked_in]->game<-[:in]-like_this WITH team, COLLECT(r) AS cards WITH team, FILTER(x IN cards: TYPE(x) = "sent_off_in") AS reds, FILTER(x IN cards: TYPE(x) = "booked_in") AS yellows RETURN team.name, LENGTH(reds) AS redCards, LENGTH(yellows) AS yellowCards ORDER BY (yellowCards*1 + redCards*3) DESC" ==>
Синтаксис при использовании функции FILTER немного изменился, поэтому нам нужно использовать предложение WHERE , а не ‘:’:
START team = node:teams('name:*') MATCH team<-[:for]-like_this<-[:started|as_sub]-player-[r?:sent_off_in|booked_in]->game<-[:in]-like_this WITH team, COLLECT(r) AS cards WITH team, FILTER(x IN cards WHERE TYPE(x) = "sent_off_in") AS reds, FILTER(x IN cards WHERE TYPE(x) = "booked_in") AS yellows RETURN team.name, LENGTH(reds) AS redCards, LENGTH(yellows) AS yellowCards ORDER BY (yellowCards*1 + redCards*3) DESC
Однако, как я намекал в начале этого поста, мы также можем перевести запрос, чтобы использовать новый для понимания. Я закончил со следующим:
START team = node:teams('name:*') MATCH team<-[:for]-like_this<-[:started|as_sub]-player-[r?:sent_off_in|booked_in]->game<-[:in]-like_this WITH team, COLLECT(r) AS cards WITH team, [card IN cards WHERE TYPE(card) = "sent_off_in"] as reds, [card in cards WHERE TYPE(card) = "booked_in"] as yellows RETURN team.name, LENGTH(reds) AS redCards, LENGTH(yellows) AS yellowCards ORDER BY (yellowCards*1 + redCards*3) DESC
Синтаксис похож на понимание списка Python, и в руководстве есть ряд примеров, которым вы можете следовать.
Запрос, который я хотел написать в мае, но должен был оставить его до тех пор, пока не будут реализованы списки, — это следующий запрос, который находит 5 лучших бомбардиров за каждый месяц и также возвращает их цели:
START month = node:months('name:*') MATCH month-[:in_month]-game-[:scored_in]-player WITH month, player, COUNT(game) AS games ORDER BY games DESC WITH month, [x IN COLLECT([player.name, games])[0..5] | x[0]] AS players, [x IN COLLECT([player.name, games])[0..5] | x[1]] AS goals ORDER BY month.position RETURN month.name, players, goals
Моя предыдущая попытка была завалена призывами к HEAD и TAIL, но эта версия намного более краткая. Вот что он возвращает:
==> +--------------------------------------------------------------------------------------------------------------------+ ==> | month.name | players | goals | ==> +--------------------------------------------------------------------------------------------------------------------+ ==> | "August" | ["Michu","Nathan Dyer","Fernando Torres","Mladen Petric","Damien Duff"] | [3,2,2,2,2] | ==> | "September" | ["Demba Ba","Steven Fletcher","Peter Crouch","Robin Van Persie","Luis Suárez"] | [5,5,4,4,4] | ==> | "October" | ["Juan Mata","Wayne Rooney","Jose Fonte","Michu","Grant Holt"] | [3,2,2,2,2] | ==> | "November" | ["Marouane Fellaini","Luis Suárez","Gareth Bale","Sergio Agüero","Olivier Giroud"] | [4,4,3,3,3] | ==> | "December" | ["Demba Ba","Wayne Rooney","Robin Van Persie","Michu","Theo Walcott"] | [5,5,5,5,4] | ==> | "January" | ["Adam Le Fondre","Luis Suárez","Robin Van Persie","Frank Lampard","Leighton Baines"] | [5,4,4,3,3] | ==> | "February" | ["Gareth Bale","Romelu Lukaku","Moussa Sissoko","Christian Benteke","Santi Cazorla"] | [5,3,3,3,3] | ==> | "March" | ["Luis Suárez","Jan Vertonghen","Christian Benteke","Shinji Kagawa","Stewart Downing"] | [4,3,3,3,2] | ==> | "April" | ["Robin Van Persie","Christian Benteke","Daniel Sturridge","Oscar","Andrew Carroll"] | [6,4,3,2,2] | ==> | "May" | ["Grant Holt","Romelu Lukaku","Daniel Sturridge","Kevin Nolan","Theo Walcott"] | [3,3,3,3,2] | ==> +--------------------------------------------------------------------------------------------------------------------+ ==> 10 rows
Если вам нравится шифр и вы еще не играли со списками, я бы порекомендовал его — этот синтаксис поможет значительно снизить сложность некоторых запросов.