CPhoto by shen liu on Unsplash

May 13: Formula 1, One Month Graph Challenge

Vlad Batushkov
May 13 · 4 min read

Welcome word

In this series of small posts I do one simple graph daily. Domain model of graph somehow related to day’s history, some historical event, celebration or person. I do this challenge to learn Neo4j Data Modeling and Cypher. Every day. One month. Follow me. Maybe you will be inspired and next month would be yours One Month Graph Challenge. #OMGChallenge

Domain model

This day 69 years ago in Silverstone, England, the first race of the first Formula 1 championship took a place. And so far Formula 1 is one of the most spectacular events in the world. I remember my first childhood TV sessions when I watching Schumacher victories in Benetton team.

Today I want to analyse results of whole history of Formula 1 competition and find the best of the best pilots ever.

Let’s think a little bit about how to organize our graph. How to say that a particular pilot in a particular year won in a particular country? In the graph database language it is mean: you should to take a year node, take a country node, take a pilot node and connect them together — to get a winner node. So, winner is N-ary relationship node based on other 3 nodes. Here is the result schema:


Parse data results of Formula 1 from official website:

Winner is an aggregation root, it can includes all necessary information of these 3 nodes, so I put all three properties inside winner. Now I can say that pilot, country and year is kind of normalized nodes, while winner is kind of denormalized node. I can read only winner nodes to know everything around. Very useful for reading purposes.

One thing to add here. I got unexpected result from apoc.load.html with 2 projections. By documentation output must be a Map type with of this structure:

A: { name: <list of elements>, name2: <list of elements> }

But unfortunately, I got result of this structure:

B: [ { name: <list of elements> }, { name2: <list of elements> } ]

So, I wrote this 2 magic lines to transform A into B:

WITH collect(value) as data
WITH { pilots: data[0].pilot, places: data[1].place } as root

Now let’s find the best of the best. A person with the most victories in all history of Formula 1:

For sure, Michael Schumacher! I didn’t expect another answer. But as you can see Hamilton can do a history very soon. Write a query for this was very easy. And if you want to find the best pilots for each concrete races, it is also super simple:

Vlad Batushkov

Written by

Indie view on software development. Brewed with hops, web and rock’n’roll.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade