Repository navigation
Workshop Steps!
Load the sample Movies Graph and follow along!
Creating John Doe (if you do not have CONSTRAINTS defined, CREATE will not ensure uniqueness)
CREATE (:Person {name: "John Doe", born: 1990});
Finding John Doe
MATCH (p:Person {name: "John Doe"})
RETURN p;
Attaching John Doe to The Matrix
MATCH (m:Movie {title: "The Matrix"})
MATCH (p:Person {name: "John Doe"})
CREATE pattern=(p)-[:ACTED_IN
{roles: ["Himself"]}]->(m)
RETURN pattern;
Describing John Doe and movies he acted in
MATCH (p:Person {name: "John Doe"})-[a:ACTED_IN]->(m:Movie)
RETURN p,a,m;
Deleting John Doe and its relationship
MATCH (p:Person {name: "John Doe"})
DETACH DELETE p;
Finding Tom
MATCH (p:Person {name: "Tom Hanks"})
RETURN p;
MATCH (p:Person)
WHERE p.name = "Tom Hanks"
RETURN p;
MATCH (p:Person WHERE p.name = "Tom Hanks")
RETURN p;
How do I know whether they're all equivalent? use PROFILE to check the query execution plan generated
PROFILE
MATCH (p:Person {name: "Tom Hanks"})
RETURN p;
PROFILE
MATCH (p:Person)
WHERE p.name = "Tom Hanks"
RETURN p;
PROFILE
MATCH (p:Person WHERE p.name = "Tom Hanks")
RETURN p;
Fetching graph elements
MATCH (p:Person {name: "Tom Hanks"})-[x:ACTED_IN]->(m:Movie)
RETURN p.name, x.roles, m.title;
Fetching counts
MATCH (p:Person {name: "Tom Hanks"})-[x:ACTED_IN|DIRECTED]->(m:Movie)
RETURN p.name, count(DISTINCT m);
Fetch all directors
MATCH (p:Person)-[:DIRECTED]->()
RETURN p.name;
MATCH (p:Person)-[:DIRECTED]->()
RETURN DISTINCT p.name;
MATCH (p:Person)
WHERE EXISTS { (p)-[:DIRECTED]->() }
RETURN p.name;
MATCH (p:Person WHERE EXISTS { (p)-[:DIRECTED]->() })
RETURN p.name;
Fetch directors with the movies they directed
MATCH (p:Person)-[:DIRECTED]->(m:Movie)
RETURN p.name AS director, COLLECT(m.title) AS moviesDirected;
Use of COLLECT and COUNT - aggregation functions
MATCH (m:Movie {title: "The Matrix"})<-[:ACTED_IN]-(p:Person)
RETURN m.title AS title, collect(p.name) AS cast, count(p) AS sizecast;
MATCH (m:Movie)<-[:ACTED_IN]-(p:Person)
WITH m.title AS title, m.released AS released, collect(p.name) AS cast
RETURN title, released, cast, size(cast) AS sizecast;
Use of OPTIONAL MATCH Find me persons with the number of movies possibly acted in and possibly directed
MATCH (p:Person)
OPTIONAL MATCH (p)-[:ACTED_IN]->(m:Movie)
WITH p, count(m) AS acts
OPTIONAL MATCH (p)-[:DIRECTED]->(m:Movie)
RETURN p.name AS person, acts, count(m) AS directs;
Use of pattern comprehension (OPTIONAL MATCH + COLLECT)
MATCH (p:Person)
RETURN p.name AS person,
size([(p)-[:ACTED_IN]->(m:Movie) | m]) AS acts,
size([(p)-[:DIRECTED]->(m:Movie) | m]) AS directs;
Did Tom act with Kevin ?
MATCH (p1:Person)-[a1:ACTED_IN]->(m:Movie)<-[a2:ACTED_IN]-(p2:Person)
WHERE p1.name = "Tom Hanks"
AND p2.name = "Kevin Bacon"
RETURN p1.name, a1.roles, p2.name, a2.roles, m.title;
Who should play with Tom - a recommendation!
MATCH (tom:Person {name: "Tom Hanks"})-[:ACTED_IN]->(m1:Movie)<-[:ACTED_IN]-(coActor:Person)-[:ACTED_IN]->(m2:Movie)<-[:ACTED_IN]-(coCoActor:Person)
WHERE NOT (tom)-[:ACTED_IN]->()<-[:ACTED_IN]-(coCoActor)
AND tom <> coCoActor
RETURN coCoActor.name AS recommendedActor, collect(DISTINCT coActor.name) AS commonCoActor, count(DISTINCT coActor.name) AS strength
ORDER BY strength DESC;
Who can introduce Tom Hanks to Tom Cruise?
MATCH (hanks:Person {name:"Tom Hanks"})-[:ACTED_IN]->(m1)<-[:ACTED_IN]-(coActors),
(coActors)-[:ACTED_IN]->(m2)<-[:ACTED_IN]-(cruise:Person {name:"Tom Cruise"})
RETURN hanks, m1, coActors, m2, cruise
Map projection** (+ pattern comprehension) List all movies with its cast (actors), directors, producers, script writers and reviewers
MATCH (m:Movie)
WHERE EXISTS(()-[:REVIEWED]->(m))
RETURN
m { .title,
.released,
actors: [(a:Person)-[:ACTED_IN]->(m)| a.name],
directors: [(d:Person)-[:DIRECTED]->(m)| d.name],
producers: [(p:Person)-[:PRODUCED]->(m)| p.name],
script: [(s:Person)-[:WROTE]->(m)| s.name],
reviews:
apoc.coll.sortMaps([(:Person)-[r:REVIEWED]->(m)| r {.rating,
.summary}], "rating")[..5]
} AS movie
LIMIT 5;