5.2. Social Movie Database

Our example graph consists of movies with title and year and actors with a name. Actors have ACTS_IN relationships to movies, which represents the role they played. This relationship also has a role attribute.

So far, we queried the movie data; now let’s update the graph too.

CREATE (matrix1:Movie { title : 'The Matrix', year : '1999-03-31' })
CREATE (matrix2:Movie { title : 'The Matrix Reloaded', year : '2003-05-07' })
CREATE (matrix3:Movie { title : 'The Matrix Revolutions', year : '2003-10-27' })
CREATE (keanu:Actor { name:'Keanu Reeves' })
CREATE (laurence:Actor { name:'Laurence Fishburne' })
CREATE (carrieanne:Actor { name:'Carrie-Anne Moss' })
CREATE (keanu)-[:ACTS_IN { role : 'Neo' }]->(matrix1)
CREATE (keanu)-[:ACTS_IN { role : 'Neo' }]->(matrix2)
CREATE (keanu)-[:ACTS_IN { role : 'Neo' }]->(matrix3)
CREATE (laurence)-[:ACTS_IN { role : 'Morpheus' }]->(matrix1)
CREATE (laurence)-[:ACTS_IN { role : 'Morpheus' }]->(matrix2)
CREATE (laurence)-[:ACTS_IN { role : 'Morpheus' }]->(matrix3)
CREATE (carrieanne)-[:ACTS_IN { role : 'Trinity' }]->(matrix1)
CREATE (carrieanne)-[:ACTS_IN { role : 'Trinity' }]->(matrix2)
CREATE (carrieanne)-[:ACTS_IN { role : 'Trinity' }]->(matrix3)

We will add ourselves, friends and movie ratings.

Here’s how to add a node for yourself and return it, let’s say your name is “Me”:

CREATE (me:User { name: "Me" })
RETURN me;
me
1 row
Nodes created: 1
Properties set: 1
Labels added: 1

Node[6]{name:"Me"}

Let’s check if the node is there:

MATCH (me:User { name: "Me" })
RETURN me.name;

Add a movie rating:

MATCH (me:User { name: "Me" }),(movie:Movie { title: "The Matrix" })
CREATE (me)-[:RATED { stars : 5, comment : "I love that movie!" }]->(movie);

Which movies did I rate?

MATCH (me:User { name: "Me" }),(me)-[rating:RATED]->(movie)
RETURN movie.title, rating.stars, rating.comment;
movie.titlerating.starsrating.comment
1 row

"The Matrix"

5

"I love that movie!"

We need a friend!

CREATE (friend:User { name: "A Friend" })
RETURN friend;

Add our friendship idempotently, so we can re-run the query without adding it several times. We return the relationship to check that it has not been created several times.

MATCH (me:User { name: "Me" }),(friend:User { name: "A Friend" })
CREATE UNIQUE (me)-[friendship:FRIEND]->(friend)
RETURN friendship;

You can rerun the query, see that it doesn’t change anything the second time!

Let’s update our friendship with a since property:

MATCH (me:User { name: "Me" })-[friendship:FRIEND]->(friend:User { name: "A Friend" })
SET friendship.since='forever'
RETURN friendship;

Let’s pretend us being our friend and wanting to see which movies our friends have rated.

MATCH (me:User { name: "A Friend" })-[:FRIEND]-(friend)-[rating:RATED]->(movie)
RETURN movie.title, avg(rating.stars) AS stars, collect(rating.comment) AS comments, count(*);
movie.titlestarscommentscount(*)
1 row

"The Matrix"

5.0

["I love that movie!"]

1

That’s too little data, let’s add some more friends and friendships.

MATCH (me:User { name: "Me" })
FOREACH (i IN range(1,10)| CREATE (friend:User { name: "Friend " + i }),(me)-[:FRIEND]->(friend));

Show all our friends:

MATCH (me:User { name: "Me" })-[r:FRIEND]->(friend)
RETURN type(r) AS friendship, friend.name;
friendshipfriend.name
11 rows

"FRIEND"

"Friend 5"

"FRIEND"

"Friend 4"

"FRIEND"

"Friend 3"

"FRIEND"

"Friend 2"

"FRIEND"

"Friend 1"

"FRIEND"

"Friend 10"

"FRIEND"

"Friend 8"

"FRIEND"

"Friend 9"

"FRIEND"

"Friend 6"

"FRIEND"

"Friend 7"

"FRIEND"

"A Friend"