Embracing the Messiness in Search of Epic Solutions

Neo4j: Playing with Cypher Query Language

Posted

in

,

PROBLEM

Every week, my shitty coworkers struggle to reach consensus on where to go for lunches and what beverages to order in the morning.

SOLUTION

To further understand the phenomenon of this first world problem, here’s a shitty graph database powered by Neo4j to visualize the love/hate relationship between my shitty coworkers and the shitty restaurants/beverages.

Now, let’s flex the power of Cypher Query Language to unclutter this shitty mess.

People who love Whistle Binkies

MATCH (p:Person)-[:loves]->(:Restaurant{name:'Whistle Binkies'})
RETURN p.name as PERSON

… OR …

MATCH (p:Person)-[:loves]->(r:Restaurant)
WHERE r.name = 'Whistle Binkies'
RETURN p.name as PERSON

Result:-

PERSON
Mike
Corey
Jason

Restaurants with at least 2 people loving it

MATCH (:Person)-[:loves]->(r:Restaurant)
WITH r, count(*) as tr
WHERE tr > 2
RETURN r.name as RESTAURANT, tr as TOTAL

Result:-

RESTAURANT         TOTAL
Whistle Binkies    3
Newts              5
John Hardy's       3
Noodles and Co     4

Restaurants that everyone loves

Winner winner chicken dinner!

MATCH (p:Person)
WITH distinct count(*) as tp
MATCH (p)-[:loves]->(r:Restaurant)
WITH tp, r, count(*) as tr
WHERE tr = tp
RETURN r.name as RESTAURANT

Result:-

RESTAURANT
Newts

Beverages that only one person loves… and find out who that weirdo is

MATCH (p:Person)-[:loves]->(b1:Beverage)
WITH b1, count(*) as tb
WHERE tb = 1
MATCH (p)-[:loves]->(b2:Beverage)
WHERE b1.name = b2.name
RETURN p.name as PERSON, b1.name as BEVERAGE

… OR …

MATCH (p:Person)-[:loves]->(b:Beverage)
WITH b, count(*) as tb
WHERE tb = 1
MATCH (p)-[:loves]->(:Beverage{name:b.name})
RETURN p.name as PERSON, b.name as BEVERAGE

Result:-

PERSON    BEVERAGE
Cory      Fufu Drink
Corey     Vanilla Latte

People who love to eat at John Hardies and drink Cold Press… ie: people with high taste

MATCH (b:Beverage)<-[:loves]-(p:Person)-[:loves]->(r:Restaurant)
WHERE r.name = "John Hardy's" and b.name = 'Cold Press'
RETURN p.name as PERSON

… OR …

MATCH (b:Beverage{name:'Cold Press'})<-[:loves]-(p:Person)-[:loves]->(r:Restaurant{name:"John Hardy's"})
RETURN p.name as PERSON

… OR …

MATCH (p:Person)-[:loves]->(r:Restaurant{name:"John Hardy's"}),
      (p)-[:loves]->(b:Beverage{name:'Cold Press'})
RETURN p.name as PERSON

Result:-

PERSON
Mike
Jason

People who love and hate the same beverage

“When love and hate collide” – Def Leppard… ie: coworkers with identity crisis.

MATCH (b:Beverage)<-[:loves]-(p:Person)-[:hates]->(:Beverage{name:b.name})
RETURN p.name as PERSON, b.name as BEVERAGE

… OR …

MATCH (p:Person)-[:loves]->(b:Beverage),
      (p)-[:hates]->(:Beverage{name:b.name})
RETURN p.name as PERSON, b.name as BEVERAGE

Result:-

PERSON    BEVERAGE
Corey     Dark Roast

LESSON LEARNED

While Cypher Query Language syntax looks much different than SQL syntax, they are pretty easy to learn and understand.

Cypher Query Language doesn’t and will not solve people problem though. We still argue about lunches/beverages every week and those who are willing to drive usually win the arguments.

Comments

Leave a Reply