Codementor Events

My neo4j Music Album Model Gets Kind of Blue

Published Jul 17, 2017
My neo4j Music Album Model Gets Kind of Blue

After a digression into something new I learned about Cypher, another brief disgression.

I've labeled the relationship between a :Musician and an :Album with an edge labeled :PLAYED_ON. I learned that I could embed a space, and I don't need an escape character. All I have to do is pre-pend the name with a back-tick, e.g., :`PLAYED ON`. If you use The Arrow Tool, you'll find that your nodes get labeled `0`, `1`,... In other words, you can use the back-tick to give your variables names that would otherwise be disallowed.

That out of the way, let's get back to the music database I've been using to learn more about Graph Databases, and neo4j and Cypher in particular.

Recall that I have a set of nodes representing musicians, another set representing music albums, and finally vertices tying them together. Below is my cypher code to establish those relationships. I wouldn't advise you to run it though since I had to change this eventually. Besides, I feel like making another set of .cypher scripts, with the relationships labeled :`PLAYED ON` next time 'round.

MERGE (M:Musician {name:"Miles Davis"}) 
WITH M MATCH (A:Album {name:"In a Silent Way"}) 
MERGE (M)-[:PLAYED_ON {instrument:"Trumpet"}]->(A);

MERGE (M:Musician {name:"Wayne Shorter"}) 
WITH M MATCH (A:Album {name:"In a Silent Way"}) 
MERGE (M)-[:PLAYED_ON {instrument:"Soprano Sax"}]->(A);

MERGE (M:Musician {name:"John McLaughlin"} 
WITH M MATCH (A:Album {name:"In a Silent Way"}) 
MERGE (M)-[:PLAYED_ON {instrument:"Electric Guitar"}]->(A);

MERGE (M:Musician {name:"Chick Corea"} 
WITH M MATCH (A:Album {name:"In a Silent Way"}) 
MERGE (M)-[:PLAYED_ON {instrument:"Electric Piano"}]->(A);

MERGE (M:Musician {name:"Herbie Hancock"} 
WITH M MATCH (A:Album {name:"In a Silent Way"}) 
MERGE (M)-[:PLAYED_ON {instrument:"Electric Piano"}]->(A);

MERGE (M:Musician {name:"Joe Zawinul"} 
WITH M MATCH (A:Album {name:"In a Silent Way"}) 
MERGE (M)-[:PLAYED_ON {instrument:"Organ"}]->(A);

MERGE (M:Musician {name:"Dave Holland"} 
WITH M MATCH (A:Album {name:"In a Silent Way"}) 
MERGE (M)-[:PLAYED_ON {instrument:"Double Bass"}]->(A);

MERGE (M:Musician {name:"Tony Williams"} 
WITH M MATCH (A:Album {name:"In a Silent Way"}) 
MERGE (M)-[:PLAYED_ON {instrument:"Drums"}]->(A);

This model is fine for the :Album In a Silent Way.

It breaks down for Kind of Blue, because Cannonball Adderley doesn't play on the third track, the second occurrence of "Shhh". Meanwhile, Bill Evans doesn't play on the second track, "Peaceful", and Paul Chambers plays only on that track.

The solution sounds simple enough — attach a tracks property to the :PLAYED_ON relationship, e.g.,

MERGE (M:Musician {name:"Bill Evans"} 
WITH M MATCH (A:Album {name:"Kind of Blue"}) 
MERGE (M)-[:PLAYED_ON {instrument:"Piano", tracks:[1,3,4,5]}]->(A);

The code for Kind of Blue is then:

MERGE (M:Musician {name:"Miles Davis"} 
WITH M MATCH (A:Album {name:"Kind of Blue"}) 
MERGE (M)-[:PLAYED_ON {instrument:"Trumpet"}]->(A);

MERGE (M:Musician {name:"Cannonball Adderley"} 
WITH M MATCH (A:Album {name:"Kind of Blue"}) 
MERGE (M)-[:PLAYED_ON {instrument:"Alto Sax", tracks:[1,2,4,5]}]->(A);

MERGE (M:Musician {name:"John Coltrane"} 
WITH M MATCH (A:Album {name:"Kind of Blue"}) 
MERGE (M)-[:PLAYED_ON {instrument:"Tenor Sax"}]->(A);

MERGE (M:Musician {name:"Bill Evans"} 
WITH M MATCH (A:Album {name:"Kind of Blue"}) 
MERGE (M)-[:PLAYED_ON {instrument:"Piano", tracks:[1,3,4,5]}]->(A);

MERGE (M:Musician {name:"Wynton Kellly"} 
WITH M MATCH (A:Album {name:"Kind of Blue"}) 
MERGE (M)-[:PLAYED_ON {instrument:"Piano", tracks:[2]}]->(A);

MERGE (M:Musician {name:"Paul Chambers"} 
WITH M MATCH (A:Album {name:"Kind of Blue"})
MERGE (M)-[:PLAYED_ON {instrument:"Double Bass"}]->(A);

MERGE (M:Musician {name:"Jimmy Cobb"}
WITH M MATCH (A:Album {name:"Kind of Blue"})
MERGE (M)-[:PLAYED_ON {instrument:"Drums"}]->(A);

The model was OK again. At least, until Bitches Brew.

Juma Santos plays both Congas and the Shaker on the second, fourth, and sixth tracks, and the Shaker on the third in addition. I decided to cheat and make a relationship vertex for each instrument. That is,

(:Musician {name:"Juma Santos"})-[:PLAYED_ON {instrument: "Congas", 
tracks:[2, 4, 6]}]->(:Album {name:"Bitches Brew"})

and

(:Musician {name:"Juma Santos"})-[:PLAYED_ON {instrument: "Shaker", 
tracks:[2, 3, 4, 6]}]->(:Album {name:"Bitches Brew"})

I did the same with Airto Moreira, who plays both Percussion and the Cuica on track 6, i.e., two relationship vertices, one for each instrument, both with the same tracks[] property.

The model still worked, albeit not as elegantly as I'd wanted, for the remainder of the :Album nodes. Here's what the graph looks like so far:
graph(1).png

Then Al Di Meola's albums came in. More on that in the next post.

Discover and read more posts from Daniel Escasa
get started
post commentsBe the first to share your opinion
Show more replies