Friday, 15 June 2018

Exploring new datatypes in Neo4j 3.4 and the Open Beer Database - part 2/2

In the previous blogpost I imported the Open Beer Database into Neo4j and added some new fancy spatial data to it. Now in this post I would like to explore that data. As a reminder, you can find the full
Let's take a look.

First we will just look at the basic OpenBeerDB data. The schema is quite straightforward:
Just Beers, Categories, Styles, Beerers (the scientific term for people that do something with Beer, apparently), Breweries and ... Geocodes. So let's try some simple queries:
//Beers for a particular category
MATCH (category:Category {categoryName: "German Lager"}) <- [:BEER_CATEGORY]- (beer:Beer)
RETURN DISTINCT(beer.beerName) as beer;
Gives me very straightforward, and seemingly correct and consistent results.
Of course there's other things we can do, but here we now want to focus on the geospatial properties that are now on the Geocode nodes. Let's try something - calculating the distance between two locations:
//grab a geocode and the 10 closest other geocodes
MATCH (n1:Geocode)
with n1
limit 1
match (n2:Geocode)
with n1, n2, distance(n1.location, n2.location) as distance
order by distance asc
limit 10
return n1.geocodeID, n2.geocodeID, distance
That's cool, and seems to work quite well:
Then I can expand on this, and actually return some graphyness around these nodes. When I run
//for these geocodes, see what breweries they have
MATCH (n1:Geocode)
with n1
limit 1
match (n2:Geocode)
with n1, n2, distance(n1.location, n2.location) as distance
order by distance asc
limit 10
with n1,n2
match path1 = ((n1)-[r1*..2]-()), path2 = ((n2)-[r2*..2]-())return path1, path2;
this query allows me to explore what's around these breweries in my neighborhood.
And then I can go one step further, and look for all the paths between these breweries, by running
match (n1:Geocode)
with n1
limit 1
match (n2:Geocode)
with n1, n2, distance(n1.location, n2.location) as distance
order by distance asc
limit 10
match path = shortestpath ((n1)-[*]-(n2))
where id(n1)<id(n2)
return path;

And that starts to look very interesting and worthy of further exploration.
I can do other things of well of course, like look for beers in a 200km range around Seattle:
WITH point({latitude: 47.608013, longitude: -122.335167}) AS seattle
MATCH path = (g:Geocode)--(br:Brewery)--(b:Beer)
WHERE distance(g.location, seattle) < 200000
RETURN path
and explore that
Or explore it a little more by including the Style nodes of the beer, and get something a little more interconnected:
WITH point({latitude: 47.608013, longitude: -122.335167}) AS seattle
MATCH path = (g:Geocode)--(br:Brewery)--(b:Beer)--(s:Style)
WHERE distance(g.location, seattle) < 200000
RETURN path
Which looks like this:
And of course I found that I wanted to do that for coordinates a bit closer to my home, and unfortunately got a much sparser graph.
Seems like the OpenBeerDB still does not have all the wonderful Belgian Beers yet - I will have to figure out a way to get that in there some day.

Hope that was useful, and that you will enjoy all the wonderful new stuff in Neo4j 3.4 as much as I have.

Cheers

Rik

No comments:

Post a comment