Category Archives: Cypher Query Language

Neo4j: WHERE Clause vs Curly Braces in MATCH Clause

PROBLEM

With Cypher Query Language, you can write similar queries that yield the same result.

For example:-

MATCH (p:Person)-[:loves]->(b:Beverage) 
WHERE b.name = 'Dark Roast' 
RETURN p.name as PERSON

… AND …

MATCH (p:Person)-[:loves]->(b:Beverage{name:'Dark Roast'}) 
RETURN p.name as PERSON

… returns the same result.

So, which one is better in terms of performance?

SOLUTION

Neo4j provides a very helpful command called EXPLAIN that allows us to do some investigation ourselves.

The EXPLAIN command displays the query plan without actually executing the query.

To use it, just add EXPLAIN in front of the query.

In this example, both queries produce exactly the same query plan.

In another word, while both queries look slightly different, they perform exactly the same.

Advertisements

Neo4j: Playing with Cypher Query Language

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.