Loading deck
Based on Online Training by Neo4j: Getting Started with Neo4j
a
b
(a) --> (b)
Connections
a
(a) --> ()
Query
a
(a) -[r]-> ()
Querying relationships
r
a
(a:Person)
Labels
Person
a
m
-[:ACTED:IN]->
Type of relationship
a
(a) -[:ACTED_IN]-> (m)
Querying ACTED_IN
a
(a) -[:DIRECTED]-> (m)
Querying DIRECTED
ACTED_IN
ACTED_IN
m
DIRECTED
m
Labels allow us to distinguish between different types of nodes
Any Node can have one or more labels.
(a:Person)
(a:Person {name:"Keanu Reeves"})
(a:Person)-[:ACTED_IN]->(m:Movie)
Both Nodes and Relationships can have Properties.
Properties are key:value pairs used to add information about the nodes and relationships.
(m {title:"The Matrix"})
(a {name:"Keanu Reeves",born:1964})
(a)-[:ACTED_IN {roles:["Neo"]}]->(m)
Properties can be attached to both nodes and relationships and are referred to by node.property or relationship.property.
MATCH (node) RETURN node.property
MATCH (node1)-->(node2)
RETURN node2.propertyA, node2.propertyB
Return every node that is related with another node
MATCH(n)-->()
RETURN n
Returning properties
MATCH(person)-->()
RETURN person.name
Return every single node in the graph
MATCH(n)
RETURN n
Return all the node pairs connected
MATCH(n)-->(m)
RETURN n, m
About relationships in queries:
MATCH(person)-[rel]->(movie)
RETURN rel
Relationships between persons and movies
MATCH (node1)-[rel:TYPE]->(node2)
RETURN rel.property
MATCH(person)-[:ACTED_IN]->(movie)
RETURN person.name, movie.title
Return the stars of the movies
MATCH(person)-[role:ACTED_IN]->(movie)
RETURN person.name, role.roles, movie.title
Return the stars of the movies and their character
Return the directors and movies actors have worked in
MATCH (actor)-[:ACTED_IN]->(movie)<-[:DIRECTED]-(director)
RETURN actor.name, movie.title, director.name
MATCH (actor)-[:ACTED_IN]->(movie),
(movie)<-[:DIRECTED]-(director)
RETURN actor.name, movie.title, director.name
MATCH (actor)-[:ACTED_IN]->(movie),
(director)-[:DIRECTED]->(movie)
RETURN actor.name, movie.title, director.name
Alternative notations
MATCH (node:Label) RETURN node
MATCH (node1:Label1)-[:REL_TYPE]->(node2:Label2)
RETURN node1, node2
MATCH(actor:Person)-[:ACTED_IN]->(movie)
RETURN actor.name, movie.title
Return the stars of the movies using node Labels
MATCH(tom:Person)
WHERE tom.name = "Tom Hanks"
RETURN tom
Return the node of Tom Hanks
Return all characters in the Movie Matrix
MATCH (actor:Person)-[role:ACTED_IN]->(movie:Movie)
WHERE movie.title = "The Matrix"
RETURN role.roles, actor.name
(a)-->(b)-->(c) is equivalent to (c)<--(b)<--(a)
We can name paths and return them as part of the result.
MATCH p=(a)-[:ACTED_IN]->(m)<-[:DIRECTED]-(d)
RETURN p
MATCH p=(a)-[:ACTED_IN]->(m)<-[:DIRECTED]-(d)
RETURN nodes(p)
MATCH p=(a)-[:ACTED_IN]->(m)<-[:DIRECTED]-(d)
RETURN rels(p)
Return the paths of directors and movies actors have worked in
(Returns all the nodes and relationships of the paths)
Only nodes
Only relationships
We can name paths and return them as part of the result.
MATCH (a)-[:ACTED_IN]->(m)<-[:DIRECTED]-(a)
RETURN a.name, m.title;
MATCH p=(a)-[:ACTED_IN]->(m)<-[:DIRECTED]-(d)
RETURN nodes(p)
MATCH p=(a)-[:ACTED_IN]->(m)<-[:DIRECTED]-(d)
RETURN rels(p)
Return the paths of directors and movies actors have worked in
(Returns all the nodes and relationships of the paths)
Only nodes
Only relationships
Neo4j stores information in graphs comprised of :
Both nodes and relationships have key:value properties (the name of an actor, the title of a movie or the roles that an actor played in a movie).
MATCH: Describe patterns
WHERE: Constraint the result set
RETURN: Get the information we want
Return the node of persons named Tom Hanks
MATCH(n:Person)
WHERE n.name = "Tom Hanks"
RETURN n
Return the name and year or birth of actors ordered by year of birth
MATCH (a:Person)-[:ACTED_IN]->()
RETURN a.name, a.born
ORDER BY a.born
SKIP 10
LIMIT 10
The same but skipping 10 and limiting 10 for paging issues
MATCH (a:Person)-[:ACTED_IN]->()
RETURN a.name, a.born
ORDER BY a.born
SKIP 10
LIMIT 10
Return the name and year or birth of actors ordered by year of birth showing only distinct results
MATCH (a:Person)-[:ACTED_IN]->()
RETURN DISTINCT a.name, a.born
ORDER BY a.born
Return all the relationships of persons
MATCH (p:Person)-[rel]->()
RETURN DISTINCT type(rel)
Return the labels of nodes having the property name
MATCH (n)
WHERE has(n.name)
RETURN DISTINCT labels(n)
Return all the movies Tom Hanks acted in
MATCH (a:Person)-[:ACTED_IN]->(m:Movie)
WHERE a.name = "Tom Hanks"
RETURN DISTINCT m
Return all the movies Keanu Reeves played the character Neo
MATCH (a:Person)-[role:ACTED_IN]->(m:Movie)
WHERE a.name = "Keanu Reeves" AND
"Neo" IN role.roles
RETURN DISTINCT m
Return all the actors who acted with Tom Hanks and are older than him
MATCH (tom:Person)-[:ACTED_IN]->(movie),
(actor:Person)->[:ACTED_IN]-(movie)
WHERE tom.name = "Tom Hanks" AND
tom.born > actor.born
RETURN DISTINCT actor.name, (tom.born - actor.born) AS diff
Return all the actors who acted with Gene Hackman and has also directed a movie
MATCH (gene:Person)-[:ACTED_IN]->(movie),
(actor:Person)-[:ACTED_IN]->(movie)
WHERE gene.name = "Gene Hackman" AND
(actor)-[:DIRECTED]->()
RETURN DISTINCT actor.name
Return all the actors who acted with Gene Hackman but not working in the same movie with Robin Williams
MATCH (gene:Person)-[:ACTED_IN]->(movie),
(actor:Person)-[:ACTED_IN]->(movie),
(robin:Person)
WHERE gene.name = "Gene Hackman" AND
robin.name = "Robin Williams" AND
NOT (robin)-[:ACTED_IN]->(movie)
RETURN DISTINCT actor.name
Return all the characters in the movie The Matrix
MATCH (actor)-[role:ACTED_IN]->(movie)
WHERE movie.title = "The Matrix"
RETURN DISTINCT role.roles
Use the Label and the property name
CREATE INDEX ON :Person(name);
CREATE INDEX ON :Movie(title);
Number of movies played by each actor [Top 5]
MATCH (actor)-[:ACTED_IN]->(movie)
RETURN actor.name, count(movie)
ORDER BY count(movie) DESC
LIMIT 5
Return all director names that each actor has ever worked with
MATCH (actor)-[:ACTED_IN]->(movie),
(director)-[:DIRECTED]->(movie)
RETURN (actor.name), collect(director.name)
Return the 3 best friend-of-a-friend actors to play with Keanu Reeves
MATCH (keanu:Person)-[:ACTED_IN]->()<-[:ACTED_IN]-(colleague),
(colleague)-[:ACTED_IN]->()<-[:ACTED_IN]-(anotherColleague)
WHERE keanu.name = "Keanu Reeves" AND
colleague <> keanu AND
NOT ((keanu)-[:ACTED_IN]->()<-[:ACTED_IN]-(anotherColleague))
RETURN anotherColleague.name, count(anotherColleague)
ORDER BY count(anotherColleague) DESC
LIMIT 3;
Return the node just created
CREATE (manolo:Person {name: "Manolo Torres"})
RETURN manolo
MATCH (p:Person)
WHERE p.name = "Manolo Torres"
RETURN p;
Return the node just created
MATCH (p:Person)
WHERE p.name = "Manolo Torres"
SET p.worksAt = "UAL"
RETURN p;
MATCH (p:Person)
WHERE p.name = "Manolo Torres"
SET p.name = "Manuel Torres"
RETURN p
MATCH (me:Person), (movie:Movie)
WHERE me.name="Manuel Torres" AND
movie.title="Top Gun"
CREATE (me)-[:REVIEWED {rating:50}]->(movie);
MATCH (a:Person), (m:Movie)
WHERE a.name = "Kevin Bacon" AND
m.title = "Mystic River"
CREATE (a)-[ACTED_IN {roles = ["Sean"]}]->(m)
Create a REVIEWED relationship between me and Top Gun with an attribute rating with value 50
Add Kevin Bacon as actor of Mystic River with the role of ["Sean"]
MATCH (me:Person), (movie:Movie)
WHERE me.name="Manuel Torres" AND
movie.title="Top Gun"
CREATE (me)-[:REVIEWED {rating:50}]->(movie);
MATCH (a:Person)-[rel:ACTED_IN]->(m:Movie)
WHERE a.name = "Kevin Bacon" AND
m.title = "Mystic River"
SET rel.roles = ["Sean Devine"]
Create a REVIEWED relationship between me and Top Gun with an attribute rating with value 50
Update the role of Kevin Bacon in Mystic River as ["Sean Devine"]
MATCH (clint:Person),(mystic:Movie)
WHERE clint.name="Clint Eastwood" AND mystic.title="Mystic River"
MERGE (clint)-[:DIRECTED]->(mystic)
RETURN clint, mystic;
Add Clint Eastwood as director of Mystic River if not exist
MATCH (a)-[:ACTED_IN|:DIRECTED]->()<-[:ACTED_IN|:DIRECTED]-(b)
WHERE NOT (a)-[:KNOWS]-(b)
MERGE (a)-[:KNOWS]->(b);
Create a KNOWS relationship between anyone who either ACTED_IN or DIRECTED the same movie
MATCH (emil:Person)
WHERE emil.name="Emil Eifrem"
OPTIONAL MATCH (emil)-[r]-()
DELETE emil,r;
Delete my node. Relationships with other nodes must also be deleted
MATCH (a:Person {name: "Keanu Reeves"})-[:KNOWS*2]->(fof)
RETURN DISTINCT fof.name
How can we get friends of friends (fof)?
MATCH (a:Person {name: "Keanu Reeves"})-[:KNOWS*3]->(fof)
RETURN DISTINCT fof.name
Length of the path
MATCH (a:Person {name: "Keanu Reeves"})-[:KNOWS*2]->(fof)
WHERE NOT (a)-[:KNOWS]->(fof)
RETURN DISTINCT fof.name
Return friends of friends that are not immediate friends?
MATCH p=shortestPath(
(keanu:Person {name: "Keanu Reeves"})-
[:KNOWS*]->
(kevin:Person {name: "Kevin Bacon"}))
RETURN length(p)
Return the length of the shortest path between two nodes following a relationship
MATCH p=shortestPath(
(keanu:Person {name: "Keanu Reeves"})-
[:KNOWS*]->
(kevin:Person {name: "Kevin Bacon"}))
RETURN nodes(p)
Return the set of nodes of the shortest path
MATCH p=shortestPath(
(keanu:Person {name: "Keanu Reeves"})-
[:KNOWS*]->
(kevin:Person {name: "Kevin Bacon"}))
RETURN [n in nodes(p) | n.name]
Return the name of the actor nodes
MATCH p=shortestPath(
(keanu:Person {name: "Keanu Reeves"})-
[:KNOWS*]->
(kevin:Person {name: "Kevin Bacon"}))
RETURN nodes(p)
Return the length of the shortest path between two nodes following a relationship
CREATE INDEX ON :Label(property)
CREATE INDEX ON :Movie(title)
CREATE INDEX ON :Person(name)
MATCH (m:Movie)<-[:ACTED_IN]-(actor)
WHERE m.title = "Cloud Atlas"
RETURN actor;
MATCH (m:Movie {title: 'Cloud Atlas'})<-[:ACTED_IN]-(actor)
RETURN actor;
Movie index enhances the performance
Alternative syntax