Skip to content

Instantly share code, notes, and snippets.

@kbastani
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kbastani/6c3df0418d9d61a1a994 to your computer and use it in GitHub Desktop.
Save kbastani/6c3df0418d9d61a1a994 to your computer and use it in GitHub Desktop.
The Oregon Brewers Festival is the quintessential celebration of craft beer!
= Craft Beers Are Everywhere in Portland =
:neo4j-version: 2.1.2
:author: Kenny Bastani
:twitter: @kennybastani
This GraphGist tells a story about why relationships matter and how craft beers seem to be everywhere in Portland.
== Like Graphs, Craft Beers Are Everywhere
Let me first start out by stating that I (http://www.twitter.com/kennybastani[@kennybastani]) am a happy evangelist for the http://www.neo4j.com[Neo4j Graph Database].
Now, if you are wondering why I am so happy, that's because I see relationships everywhere. If you don't know what a graph is yet, please allow me the opportunity to blow your mind. This is a story about graphs and craft beers in Portland.
=== Relationships Matter
Graphs are the easiest way for us meek and feeble human minds to conceptualize the world around us into relationships. The problem with this is that graphs, by their very nature, are a model of complexity. So the reason why I am so happy is that when I found Neo4j I found something that brilliantly enabled me to help manage and organize relationships in an intuitive and easy way.
=== Graph All the OSCON Tweets
image::http://i.imgur.com/MF1HZvV.jpg[Graph all the OSCON Tweet]
As a part of my global campaign to spread the word about Neo4j, I frequently get the opportunity to take something fun and turn it into a graph. As a part of Neo4j's recent sponsorship at OSCON 2014, we did all kinds of cool things to surface the relationships between Twitter users, their tweets, and what they were tweeting about.
We wrote a blog post about it here: http://neo4j.com/blog/oscon-twitter-graph/[OSCON Twitter Graph]
image::http://i.imgur.com/Dj2d6aw.jpg[Twitter Graph]
=== Beer with Friends
Some of the Neo4j team had the opportunity to make friends with some awesome Drupal developers who were native to Portland. So after the OSCON conference wrapped up, our new friends invited a few of us to take in some of the sights, sounds, and tastes of Portland. The first of those being the http://www.oregonbrewfest.com/[Oregon Brewers Festival].
== What is the Oregon Brewers Festival?
image::http://i.imgur.com/hV3UKw9.jpg[Oregon Brewers Festival]
From the BrewFest website:
"Pouring 88 different craft beers from around the country - plus another 100 in the Specialty Tent - the Oregon Brewers Festival is the quintessential celebration of craft beer! On a sun soaked July afternoon, there's no better place to sip suds with friends along the banks of the Willamette River, with the Portland skyline as a backdrop to the west and Mt. Hood towering in the east. Whether you prefer Belgians or Blondes, Pales or Pilsners, Saisons or Wits - come to the Oregon Brewers Festival, and see for yourself why we're one of the world's best loved craft beer festivals."
== The BrewFest Graph Data Model
I started by modeling out the craft beer selections at the festival using a graph data model.
image::http://i.imgur.com/AtMkYKW.jpg[Brewers Festival Data Model]
The model is pretty simple. We have craft beers, we have brewers, we have beer styles and types. I imported this data from the Oregon Brewers Festival website: http://www.oregonbrewfest.com/index2.php?p=beers
Using `LOAD CSV` in Cypher, I was able to take a cleaned format of the data from the website and add some types that grouped the styles of beer together. Doing this I was able to understand what kind of craft beers were really popular with the brewers.
== Import the Data of Beer Selection
//setup
//hide
[source,cypher]
----
USING PERIODIC COMMIT 1000
LOAD CSV WITH HEADERS FROM "https://dl.dropboxusercontent.com/s/qf60qw39j954s41/beers.txt" AS csvLine
MERGE (brewery:Brewery { name: csvLine.Brewery })
MERGE (style:Style { name: csvLine.Style })
MERGE (beer:Beer { name: csvLine.Beer })
MERGE (type:Type { name: csvLine.Type })
MERGE (brewery)-[:MAKES_BEER]->(beer)
MERGE (beer)-[:HAS_STYLE]->(style)
MERGE (style)-[:HAS_TYPE]->(type)
----
[source,cypher]
----
MATCH (n) RETURN n;
----
//graph
== What are the top 5 most popular beer styles?
First, I wanted to know what styles of beer were high in supply. No surprise here, the IPA (India Pale Ale) is the king of craft beers.
[source,cypher]
----
MATCH (type:Type)<--()--(beer:Beer)
RETURN type.name, count(beer.name) as count
ORDER BY count DESC
LIMIT 5
----
//table
== What are the most popular styles of India Pale Ale?
Now that I know the most popular kinds of craft beers by their super type, I want to see what kind of styles of the top 5 beer types were worth taking a look at. The IPA type had a broad range of choices for each variant of style.
[source,cypher]
----
MATCH (type:Type { name: "India Pale Ale" })<-[:HAS_TYPE]-(style:Style)<-[:HAS_STYLE]-(beer:Beer)
RETURN style.name, count(beer.name) AS count
ORDER BY count DESC
LIMIT 5
----
//table
== What are the most popular styles of Ale?
Next I took a look at the second most popular type of beer, which grouped together non-IPA ales. Lots of variety, not much of a selection for each of the styles. The key component of this group was novelty.
[source,cypher]
----
MATCH (type:Type { name: "Ale" })<-[:HAS_TYPE]-(style:Style)<-[:HAS_STYLE]-(beer:Beer)
RETURN style.name, count(beer.name) AS count
ORDER BY count DESC
LIMIT 5
----
//table
== What are the most popular styles of Wheat?
Now on to the wheat. The trend this year seems to be wheat with fruit, other than the classic orange. Blue Moon Brewing Company, pay attention.
[source,cypher]
----
MATCH (type:Type { name: "Wheat" })<-[:HAS_TYPE]-(style:Style)<-[:HAS_STYLE]-(beer:Beer)
RETURN style.name, count(beer.name) AS count
ORDER BY count DESC
LIMIT 5
----
//table
== What are the most popular styles of Weisse?
My German colleague, Michael Hunger (@mesirii), turned me on to this kind of German-inspired beer selection.
[source,cypher]
----
MATCH (type:Type { name: "Weisse" })<-[:HAS_TYPE]-(style:Style)<-[:HAS_STYLE]-(beer:Beer)
RETURN style.name, count(beer.name) AS count
ORDER BY count DESC
LIMIT 5
----
//table
== What are the most popular styles of Pale Ale?
[source,cypher]
----
MATCH (type:Type { name: "Pale Ale" })<-[:HAS_TYPE]-(style:Style)<-[:HAS_STYLE]-(beer:Beer)
RETURN style.name, count(beer.name) AS count
ORDER BY count DESC
LIMIT 5
----
//table
== Conclusion
It's really fun to see and understand the connections between beer and people. Beers have a pretty complex and unstructured kind of ontology, which makes it tough to understand and comprehend. This becomes more difficult to do when you are trying to make sense of which of the 88 different craft beers at the festival you should sample.
My main take away was this: relationships are what enables us to make sense of the world around us.
image::http://i.imgur.com/UDPfhKm.jpg[Fun with friends]
Cheers!
Kenny Bastani
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment