The Neo4j Manual > Tutorials > Getting started with Cypher
4.1. Create nodes and relationships
Create a node for the actor Tom Hanks:
CREATE (n:Actor { name:"Tom Hanks" });
|
Let’s find the node we created:
MATCH (actor:Actor { name: "Tom Hanks" })
RETURN actor;
|
Now let’s create a movie and connect it to the Tom Hanks node with an ACTED_IN relationship:
MATCH (actor:Actor)
WHERE actor.name = "Tom Hanks"
CREATE (movie:Movie { title:'Sleepless IN Seattle' })
CREATE (actor)-[:ACTED_IN]->(movie);
|
Using a WHERE clause in the query above to get the Tom Hanks node does the same thing as the pattern in the MATCH clause of the previous query.
This is how our graph looks now:
We can do more of the work in a single clause.CREATE UNIQUE will make sure we don’t create duplicate patterns. Using this: [r:ACTED_IN] lets us return the relationship.
MATCH (actor:Actor { name: "Tom Hanks" })
CREATE UNIQUE (actor)-[r:ACTED_IN]->(movie:Movie { title:"Forrest Gump" })
RETURN r;
|
Set a property on a node:
MATCH (actor:Actor { name: "Tom Hanks" })
SET actor.DoB = 1944
RETURN actor.name, actor.DoB;
|
The labels Actor and Movie help us organize the graph. Let’s list all Movie nodes:
MATCH (movie:Movie)
RETURN movie AS `All Movies`;
|
All Movies
|
2 rows
|
Node[1]{title:"Sleepless in Seattle"}
|
Node[2]{title:"Forrest Gump"}
|
4.2. 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.
We’ll go with three movies and three actors:
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)
|
This gives us the following graph to play with:
Let’s check how many nodes we have now:
MATCH (n)
RETURN "Hello Graph with " + count(*)+ " Nodes!" AS welcome;
|
Return a single node, by name:
MATCH (movie:Movie { title: 'The Matrix' })
RETURN movie;
|
Return the title and date of the matrix node:
MATCH (movie:Movie { title: 'The Matrix' })
RETURN movie.title, movie.year;
|
Which results in:
movie.title
|
movie.year
|
1 row
|
"The Matrix"
|
"1999-03-31"
|
Show all actors:
MATCH (actor:Actor)
RETURN actor;
|
Return just the name, and order them by name:
MATCH (actor:Actor)
RETURN actor.name
ORDER BY actor.name;
|
Count the actors:
MATCH (actor:Actor)
RETURN count(*);
|
Get only the actors whose names end with “s”:
MATCH (actor:Actor)
WHERE actor.name =~ ".*s$"
RETURN actor.name;
|
Here’s some exploratory queries for unknown datasets.Don’t do this on live production databases!
Count nodes:
MATCH (n)
RETURN count(*);
|
Count relationship types:
MATCH (n)-[r]->()
RETURN type(r), count(*);
|
type(r)
|
count(*)
|
1 row
|
"ACTS_IN"
|
9
|
List all nodes and their relationships:
MATCH (n)-[r]->(m)
RETURN n AS from, r AS `->`, m AS to;
|
from
|
->
|
to
|
9 rows
|
Node[3]{name:"Keanu Reeves"}
|
:ACTS_IN[0]{role:"Neo"}
|
Node[0]{title:"The Matrix",year:"1999-03-31"}
|
Node[3]{name:"Keanu Reeves"}
|
:ACTS_IN[1]{role:"Neo"}
|
Node[1]{title:"The Matrix Reloaded",year:"2003-05-07"}
|
Node[3]{name:"Keanu Reeves"}
|
:ACTS_IN[2]{role:"Neo"}
|
Node[2]{title:"The Matrix Revolutions",year:"2003-10-27"}
|
Node[4]{name:"Laurence Fishburne"}
|
:ACTS_IN[3]{role:"Morpheus"}
|
Node[0]{title:"The Matrix",year:"1999-03-31"}
|
Node[4]{name:"Laurence Fishburne"}
|
:ACTS_IN[4]{role:"Morpheus"}
|
Node[1]{title:"The Matrix Reloaded",year:"2003-05-07"}
|
Node[4]{name:"Laurence Fishburne"}
|
:ACTS_IN[5]{role:"Morpheus"}
|
Node[2]{title:"The Matrix Revolutions",year:"2003-10-27"}
|
Node[5]{name:"Carrie-Anne Moss"}
|
:ACTS_IN[6]{role:"Trinity"}
|
Node[0]{title:"The Matrix",year:"1999-03-31"}
|
Node[5]{name:"Carrie-Anne Moss"}
|
:ACTS_IN[7]{role:"Trinity"}
|
Node[1]{title:"The Matrix Reloaded",year:"2003-05-07"}
|
Node[5]{name:"Carrie-Anne Moss"}
|
:ACTS_IN[8]{role:"Trinity"}
|
Node[2]{title:"The Matrix Revolutions",year:"2003-10-27"}
|
4.4. Finding Paths
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.
We queried and updated the data so far, now let’s find interesting constellations, a.k.a. paths.
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)
|
All other movies that actors in “The Matrix” acted in ordered by occurrence:
MATCH (:Movie { title: "The Matrix" })<-[:ACTS_IN]-(actor)-[:ACTS_IN]->(movie)
RETURN movie.title, count(*)
ORDER BY count(*) DESC ;
|
movie.title
|
count(*)
|
2 rows
|
"The Matrix Revolutions"
|
3
|
"The Matrix Reloaded"
|
3
|
Let’s see who acted in each of these movies:
MATCH (:Movie { title: "The Matrix" })<-[:ACTS_IN]-(actor)-[:ACTS_IN]->(movie)
RETURN movie.title, collect(actor.name), count(*) AS count
ORDER BY count DESC ;
|
movie.title
|
collect(actor.name)
|
count
|
2 rows
|
"The Matrix Revolutions"
|
["Keanu Reeves","Laurence Fishburne","Carrie-Anne Moss"]
|
3
|
"The Matrix Reloaded"
|
["Keanu Reeves","Laurence Fishburne","Carrie-Anne Moss"]
|
3
|
What about co-acting, that is actors that acted together:
MATCH (:Movie { title: "The Matrix"
})<-[:ACTS_IN]-(actor)-[:ACTS_IN]->(movie)<-[:ACTS_IN]-(colleague)
RETURN actor.name, collect(DISTINCT colleague.name);
|
actor.name
|
collect(distinct colleague.name)
|
3 rows
|
"Carrie-Anne Moss"
|
["Keanu Reeves","Laurence Fishburne"]
|
"Laurence Fishburne"
|
["Keanu Reeves","Carrie-Anne Moss"]
|
"Keanu Reeves"
|
["Laurence Fishburne","Carrie-Anne Moss"]
|
Who of those other actors acted most often with anyone from the matrix cast?
MATCH (:Movie { title: "The Matrix"
})<-[:ACTS_IN]-(actor)-[:ACTS_IN]->(movie)<-[:ACTS_IN]-(colleague)
RETURN colleague.name, count(*)
ORDER BY count(*) DESC LIMIT 10;
|
colleague.name
|
count(*)
|
3 rows
|
"Carrie-Anne Moss"
|
4
|
"Keanu Reeves"
|
4
|
"Laurence Fishburne"
|
4
|
Starting with paths, a path is a sequence of nodes and relationships from a start node to an end node.
We know that Trinity loves Neo, but how many paths exist between their actors? We’ll limit the path length and the query as it exhaustively searches the graph otherwise
MATCH p =(:Actor { name: "Keanu Reeves" })-[:ACTS_IN*0..5]-(:Actor { name: "Carrie-Anne Moss" })
RETURN p, length(p)
LIMIT 10;
|
p
|
length(p)
|
9 rows
|
[Node[3]{name:"Keanu Reeves"},:ACTS_IN[0]{role:"Neo"},Node[0]{title:"The Matrix",year:"1999-03-31"},:ACTS_IN[3]{role:"Morpheus"},Node[4]{name:"Laurence Fishburne"},:ACTS_IN[4]{role:"Morpheus"},Node[1]{title:"The Matrix Reloaded",year:"2003-05-07"},:ACTS_IN[7]{role:"Trinity"},Node[5]{name:"Carrie-Anne Moss"}]
|
4
|
[Node[3]{name:"Keanu Reeves"},:ACTS_IN[0]{role:"Neo"},Node[0]{title:"The Matrix",year:"1999-03-31"},:ACTS_IN[3]{role:"Morpheus"},Node[4]{name:"Laurence Fishburne"},:ACTS_IN[5]{role:"Morpheus"},Node[2]{title:"The Matrix Revolutions",year:"2003-10-27"},:ACTS_IN[8]{role:"Trinity"},Node[5]{name:"Carrie-Anne Moss"}]
|
4
|
[Node[3]{name:"Keanu Reeves"},:ACTS_IN[0]{role:"Neo"},Node[0]{title:"The Matrix",year:"1999-03-31"},:ACTS_IN[6]{role:"Trinity"},Node[5]{name:"Carrie-Anne Moss"}]
|
2
|
[Node[3]{name:"Keanu Reeves"},:ACTS_IN[1]{role:"Neo"},Node[1]{title:"The Matrix Reloaded",year:"2003-05-07"},:ACTS_IN[4]{role:"Morpheus"},Node[4]{name:"Laurence Fishburne"},:ACTS_IN[3]{role:"Morpheus"},Node[0]{title:"The Matrix",year:"1999-03-31"},:ACTS_IN[6]{role:"Trinity"},Node[5]{name:"Carrie-Anne Moss"}]
|
4
|
[Node[3]{name:"Keanu Reeves"},:ACTS_IN[1]{role:"Neo"},Node[1]{title:"The Matrix Reloaded",year:"2003-05-07"},:ACTS_IN[4]{role:"Morpheus"},Node[4]{name:"Laurence Fishburne"},:ACTS_IN[5]{role:"Morpheus"},Node[2]{title:"The Matrix Revolutions",year:"2003-10-27"},:ACTS_IN[8]{role:"Trinity"},Node[5]{name:"Carrie-Anne Moss"}]
|
4
|
[Node[3]{name:"Keanu Reeves"},:ACTS_IN[1]{role:"Neo"},Node[1]{title:"The Matrix Reloaded",year:"2003-05-07"},:ACTS_IN[7]{role:"Trinity"},Node[5]{name:"Carrie-Anne Moss"}]
|
2
|
[Node[3]{name:"Keanu Reeves"},:ACTS_IN[2]{role:"Neo"},Node[2]{title:"The Matrix Revolutions",year:"2003-10-27"},:ACTS_IN[5]{role:"Morpheus"},Node[4]{name:"Laurence Fishburne"},:ACTS_IN[3]{role:"Morpheus"},Node[0]{title:"The Matrix",year:"1999-03-31"},:ACTS_IN[6]{role:"Trinity"},Node[5]{name:"Carrie-Anne Moss"}]
|
4
|
[Node[3]{name:"Keanu Reeves"},:ACTS_IN[2]{role:"Neo"},Node[2]{title:"The Matrix Revolutions",year:"2003-10-27"},:ACTS_IN[5]{role:"Morpheus"},Node[4]{name:"Laurence Fishburne"},:ACTS_IN[4]{role:"Morpheus"},Node[1]{title:"The Matrix Reloaded",year:"2003-05-07"},:ACTS_IN[7]{role:"Trinity"},Node[5]{name:"Carrie-Anne Moss"}]
|
4
|
[Node[3]{name:"Keanu Reeves"},:ACTS_IN[2]{role:"Neo"},Node[2]{title:"The Matrix Revolutions",year:"2003-10-27"},:ACTS_IN[8]{role:"Trinity"},Node[5]{name:"Carrie-Anne Moss"}]
|
2
|
Bur that’s a lot of data, we just want to look at the names and titles of the nodes of the path.
MATCH p =(:Actor { name: "Keanu Reeves" })-[:ACTS_IN*0..5]-(:Actor { name: "Carrie-Anne Moss" })
RETURN extract(n IN nodes(p)| coalesce(n.title,n.name)) AS `names AND titles`, length(p)
ORDER BY length(p)
LIMIT 10;
|
names and titles
|
length(p)
|
9 rows
|
["Keanu Reeves","The Matrix","Carrie-Anne Moss"]
|
2
|
["Keanu Reeves","The Matrix Reloaded","Carrie-Anne Moss"]
|
2
|
["Keanu Reeves","The Matrix Revolutions","Carrie-Anne Moss"]
|
2
|
["Keanu Reeves","The Matrix","Laurence Fishburne","The Matrix Reloaded","Carrie-Anne Moss"]
|
4
|
["Keanu Reeves","The Matrix","Laurence Fishburne","The Matrix Revolutions","Carrie-Anne Moss"]
|
4
|
["Keanu Reeves","The Matrix Reloaded","Laurence Fishburne","The Matrix","Carrie-Anne Moss"]
|
4
|
["Keanu Reeves","The Matrix Reloaded","Laurence Fishburne","The Matrix Revolutions","Carrie-Anne Moss"]
|
4
|
["Keanu Reeves","The Matrix Revolutions","Laurence Fishburne","The Matrix","Carrie-Anne Moss"]
|
4
|
["Keanu Reeves","The Matrix Revolutions","Laurence Fishburne","The Matrix Reloaded","Carrie-Anne Moss"]
|
4
|
4.5. Labels, Constraints and Indexes
Labels are a convenient way to group nodes together. They are used to restrict queries, define constraints and create indexes.
The following will give an example of how to use labels. Let’s start out adding a constraint — in this case we decided that all Movie node titles should be unique.
CREATE CONSTRAINT ON (movie:Movie) ASSERT movie.title IS UNIQUE
|
Note that adding the unique constraint will add an index on that property, so we won’t do that separately. If we drop the constraint, we will have to add an index instead, as needed.
In this case we want an index to speed up finding actors by name in the database:
CREATE INDEX ON :Actor(name)
|
Indexes can be added at any time. Constraints can be added after a label is already in use, but that requires that the existing data complies with the constraints. Note that it will take some time for an index to come online when there’s existing data.
Now, let’s add some data.
CREATE (actor:Actor { name:"Tom Hanks" }),(movie:Movie { title:'Sleepless IN Seattle' }),
(actor)-[:ACTED_IN]->(movie);
|
Normally you don’t specify indexes when querying for data. They will be used automatically. This means we can simply look up the Tom Hanks node, and the index will kick in behind the scenes to boost performance.
MATCH (actor:Actor { name: "Tom Hanks" })
RETURN actor;
|
Now let’s say we want to add another label for a node. Here’s how to do that:
MATCH (actor:Actor { name: "Tom Hanks" })
SET actor :American;
|
To remove a label from nodes, this is what to do:
MATCH (actor:Actor { name: "Tom Hanks" })
REMOVE actor:American;
|
For more information on labels and related topics, see:
-
Section 3.4, “Labels”
-
Chapter 13, Schema
-
Section 13.2, “Constraints”
-
Section 13.1, “Indexes”
-
Section 9.7, “Using”
-
Section 11.4, “Set”
-
Section 11.6, “Remove”
-
eleting graph elements — nodes and relationships, is done with DELETE.
-
For removing properties and labels, see Section 11.6, “Remove”.
-
The examples start out with the following database:
-
-
11.5.1. Delete single node
-
To delete a node, use the DELETE clause.
-
Query.
MATCH (n { name: 'Peter' })
DELETE n
| -
Nothing is returned from this query, except the count of affected nodes.
-
Result__Nodes_deleted:_1'>Result
Nodes deleted: 1
|
(empty result)
| -
-
11.5.2. Delete a node and connected relationships
-
If you are trying to delete a node with relationships on it, you have to delete these as well.
-
Query.
MATCH (n { name: 'Andres' })-[r]-()
DELETE n, r
| -
Nothing is returned from this query, except the count of affected nodes.
-
Result
Nodes deleted: 1
|
Relationships deleted: 2
|
(empty result)
| -
-
11.5.3. Delete all nodes and relationships
-
This query isn’t for deleting large amounts of data, but is nice when playing around with small example data sets.
-
Query.
MATCH (n)
OPTIONAL MATCH (n)-[r]-()
DELETE n,r
| -
Nothing is returned from this query, except the count of affected nodes.
-
Result
Nodes deleted: 3
|
Relationships deleted: 2
|
(empty result)
|
Do'stlaringiz bilan baham: |