Adventures in neo4j: a music database

Published Jul 11, 2017
Adventures in neo4j: a music database

After installing Arch Linux on my BeagleBone Black, and both the native neo4j and the neo4j Docker image, I began by building up a music database, which consisted of :Musician and :Album nodes, and a :PLAYED_ON relationship between the two. I first created the :Musician nodes with CREATE (:Musician {name:"<musician name">}),...(:Musician {name:"<musician name>") first for the musicians on Kind of Blue, then for musicians on other albums.

Next up, the albums, with CREATE (:Album {name:"<album title>", tracks:[<track-list>]),...(:Album {name:"<album title>", tracks:[<track-list>]). Just eight albums for now, although not all of them show up on the cover photo since not all of them are "related" to the musicians in the sense that I hadn't assigned the musicians to them yet.

Before I go on — I wrote those CREATE commands in text files, then dragged them into my Favorites, instead of pasting into the command window. This makes it easier to recreate the nodes.

Then the fun part: telling neo4j which musicians played on which albums. I may have made the mistake of choosing the "easiest" album first — you'll see why in a bit.

Again, I wrote the commands in a text file, then saved it in my Favorites as a Saved Script. Ran it, didn't work because the command interpreter expected one command, whereas I had about 50. No matter, just run it using $NEO4JHOME/bin/cypher-shell --address <ip-address-of-BBB> --username <neo4j-username> --password <password> < music.cypher.

The first few lines of my original .cypher were as follows:
// Personnel on In a Silent Way
MATCH (M:Musician {name:"Miles Davis"}), (M:Album {name:"In a Silent Way"}) MERGE (M)-[:PLAYED_ON {instrument:"Trumpet"}]->(A);
MATCH (M:Musician {name:"Wayne Shorter"}), (M:Album {name:"In a Silent Way"}) MERGE (M)-[:PLAYED_ON {instrument:"Soprano Sax"}]->(A);
MATCH (M:Musician {name:"John McLaughlin"}), (M:Album {name:"In a Silent Way"}) MERGE (M)-[:PLAYED_ON {instrument:"Electric Guitar"}]->(A);
MATCH (M:Musician {name:"Chick Corea"}), (M:Album {name:"In a Silent Way"}) MERGE (M)-[:PLAYED_ON {instrument:"Electric Piano"}]->(A);
MATCH (M:Musician {name:"Herbie Hancock"}), (M:Album {name:"In a Silent Way"}) MERGE (M)-[:PLAYED_ON {instrument:"Electric Piano"}]->(A);
MATCH (M:Musician {name:"Joe Zawinul"}), (M:Album {name:"In a Silent Way"}) MERGE (M)-[:PLAYED_ON {instrument:"Organ"}]->(A);
MATCH (M:Musician {name:"Dave Holland"}), (M:Album {name:"In a Silent Way"}) MERGE (M)-[:PLAYED_ON {instrument:"Double Bass"}]->(A);
MATCH (M:Musician {name:"Tony Williams"}), (M:Album {name:"In a Silent Way"}) MERGE (M)-[:PLAYED_ON {instrument:"Drums"}]->(A);

At this point though I should mention that, after I'd created Miles Davis and In a Silent Way :Musician and :Album nodes,
CREATE (:Musician {name:"Miles Davis"})-[:PLAYED_ON {instrument:"Trumpet"}]->(:Album {name:"In a Silent Way", tracks:[["Shhh", "Peaceful", "Shhh", "In a Silent Way", "It's About That Time", "In a Silent Way"]})
would result in an unpleasant suprise, creating another occurrence of the Miles Davis and In a Silent Way nodes. That's why I had to MATCH and MERGE.

I did the same thing for So far, so good. But Kind of Blue, Stardust, and Bitches Brew all presented a complication that made me change the model.

On that, in the next post.

Discover and read more posts from Daniel Escasa
get started