GraphGists

Domain Model

Each League has multiple *Level*s like playoffs, quarter-finals etc. The levels are ordered: first is playoffs, NEXT is quarter-finals, NEXT is semi-finals and then the next and last one is the finals. The ordering is represented using a linked-list.

A Player can play for more than one team over multiple leagues but can only play for a single team in a given league. This is captured by the PLAYED_IN_FOR_LEAGUE hyperedge between player, team and league using hypernode PlayerTeamLeague . A team can register in a new league with a different name in which case, we want to know what it was PREVIOUSLY_KNOWN_AS.The fact that a player had for a given team (irrespective of which league) is captured by PLAYED_WITH_TEAM between the player and team to simplify the queries.

In each level, Teams are organized into Pools and each pool consists of one or more teams. Each pool has fixtures i.e. the Matches played between two teams, TEAM_A and TEAM_B respectively. Each match is PLAYED_ON a court. Each match has a WINNER, LOSER and a MVP.

A team can have many players but only subset of them, allowed by the game rules (for e.g. only 2 players can play table tennis). This is captured by the TEAM_A_PLAYER and TEAM_B_PLAYER relationships from match to each of the players who played this match.

Each league is PLAYED_AT one or more Venues. Each venue has one or more Courts. The more the courts and venues, the faster we can complete the league.

Each league gives away certain Awards. Awards are AWARDED_TO teams and players. Teams win TEAM_AWARD s and players win INDIVIDUAL_AWARD s.

Domain Model

Setup

Let us relaize this model using Volleyball as the sport. This model (with more enhancements) will eventually be used as a database for Atlanta Volleyball League

Use Cases

League

Get all leagues and venues.

MATCH (l:League)-[:PLAYED_AT]->(v:Venue)-[:COURT]->(c:Court)
RETURN l.name AS League, v.name AS Venue, collect(c.name) AS Courts

Get total teams contested by league.

MATCH (p:Player)-[:PLAYED_FOR_IN_LEAGUE]->(hyperEdge)-[:PLAYED_FOR]->(t:Team), (hyperEdge)-[:IN_LEAGUE]->(l:League)
RETURN COUNT(DISTINCT t) AS TotalTeamsContested, l.name AS League

How many teams participated in a given league?

MATCH (t:Team)<-[:PLAYED_FOR]-(hyperEdge)-[:IN_LEAGUE]->(l:League)
WHERE l.name='September Volleyball League'
RETURN count(DISTINCT t) AS TotalTeamsContested

Get total players participated by league.

MATCH (p:Player)-[:PLAYED_FOR_IN_LEAGUE]->(hyperEdge)-[:PLAYED_FOR]->(t:Team), (hyperEdge)-[:IN_LEAGUE]->(l:League)
RETURN count(p) AS TotalPlayersContested, l.name AS League

How many players contested in a given league?

MATCH (p:Player)-[:PLAYED_FOR_IN_LEAGUE]->(hyperEdge)-[:PLAYED_FOR]->(t:Team), (hyperEdge)-[:IN_LEAGUE]->(l:League)
WHERE l.name='September Volleyball League'
RETURN count(p) AS TotalPlayersContested

How many players contested in a given league, group by Team.

MATCH (p:Player)-[:PLAYED_FOR_IN_LEAGUE]->(hyperEdge)-[:PLAYED_FOR]->(t:Team), (hyperEdge)-[:IN_LEAGUE]->(l:League)
WHERE l.name='September Volleyball League'
RETURN t.name AS Team, count(p) AS TotalPlayersContested, collect(p.name) AS Players

Where was this league organized?

MATCH (l:League)-[:PLAYED_AT]->(v:Venue)-[:COURT]->(c:Court)
WHERE l.name='September Volleyball League'
RETURN v.name AS Venue, collect(c.name) AS Courts

Get all the levels of a given league in the order they are played.

MATCH p=(league:League)-[r:LEVEL|NEXT*]->(l:Level)
WHERE league.name='September Volleyball League'
WITH last(nodes(p)) AS levels
RETURN COLLECT(levels.name) AS LevelsInOrder

Get the levels of each league.

MATCH p=(league:League)-[r:LEVEL|NEXT*]->(l:Level)
WITH last(nodes(p)) AS levels, league
RETURN league.name AS League, COLLECT(levels.name) AS LevelsInOrder

Team

Get a list of all the players that had ever played for a given team. Simplified by using the played_with_team relationship.

MATCH (p:Player)-[:PLAYED_WITH_TEAM]->(t:Team) WHERE t.name='Falcons'
RETURN p AS Players

Get a list of players for a given team for a given league.

MATCH (p:Player)-[:PLAYED_FOR_IN_LEAGUE]->(hyperEdge)-[:PLAYED_FOR]->(t:Team), (hyperEdge)-[:IN_LEAGUE]->(l:League)
WHERE l.name='September Volleyball League' AND t.name='Lakers'
RETURN p AS Players

Get all the leagues this team had played in.

MATCH (t:Team)<-[:PLAYED_FOR]-(hyperEdge)-[:IN_LEAGUE]->(l:League)
WHERE t.name='Broncos'
RETURN DISTINCT l.name AS Leagues

How many leagues this team has WON?

MATCH (l:League)-[:TEAM_AWARD]->(a:Award)-[:AWARDED_TO]->(t:Team)
WHERE t.name='Falcons'
RETURN t.name AS Team, a.name AS Award, count(t) AS TimesWon, l.name AS League

Which levels did this team win through in a given league?

MATCH (t:Team)<-[:TEAM]-(p:Pool)<-[:POOL]-(l:Level)<-[:LEVEL|NEXT*]-(league:League)
WHERE league.name='September Volleyball League'
RETURN t.name AS Team, collect(l.name) AS Levels

Get previous names or aliases.

MATCH (t:Team)-[:PREVIOUSLY_KNOWN_AS]->(other)
RETURN t.name AS CurrentName, other.name AS PreviousName

Player

How many times part of winning (winner, runner etc) Team.

MATCH (p:Player)-[:PLAYED_FOR_IN_LEAGUE]->(hyperEdge)-[:PLAYED_FOR]->(t:Team),
      (hyperEdge)-[:IN_LEAGUE]->(l:League),
      (l:League)-[:TEAM_AWARD]->(a:Award)-[:AWARDED_TO]->(t:Team)
WHERE p.name='Bob' AND a.name='Winner'
RETURN count(t) AS TimesPartOfWinningTeam

Get the co-players of a given player.

MATCH (p:Player)-[:PLAYED_WITH_TEAM]->(t:Team)<-[:PLAYED_WITH_TEAM]-(coPlayer:Player)
WHERE p.name='Alice'
RETURN coPlayer.name AS Coplayer, t.name AS FromTeam

How many MVP awards are won by the given player?

MATCH (p:Player)-[:MVP]-(m:Match)
WHERE p.name='Bob'
RETURN count(p) AS TimesWonTheMVPAward

Awards

All the awards of a given league.

MATCH (league:League)-[r:INDIVIDUAL_AWARD|TEAM_AWARD]->(award)
WHERE league.name='September Volleyball League'
RETURN award.name AS Award, TYPE(r) AS AwardType

Winners of the awards of a given league.

MATCH (league:League)-[:INDIVIDUAL_AWARD|:TEAM_AWARD]->(award:Award)-[:AWARDED_TO]->(awardee)
WHERE league.name='September Volleyball League'
RETURN award.name AS Award, awardee.name AS WonBy

GitHub Project

A complete working example of this domain can be cloned from funpluscharity/avleague. Contact yaravind@gmail.com if you want to contribute to this project or has any suggestions on enhancing the model.