Set, Create, Update, and Delete Operations

SET

The SET clause is used to update labels on nodes and properties on nodes and relationships.

Setting a property

MATCH (n {name: 'Jennifer'})
SET n.nickname = 'The Fast One'
RETURN n.name, n.nickname

Adding a label to a node

MATCH (n {name: 'Jennifer'})
SET n:Actress
RETURN n.name, labels(n) AS labels

CREATE

Adding data in Cypher works very similarly to any other data access language’s insert statement. Instead of the INSERT keyword like in SQL, though, Cypher uses CREATE.

You can use CREATE to insert :

  • nodes

  • relationships

  • patterns

CREATE (n:Person {name: 'Mark'})

Note

You have to be careful not to run the create statement more than once. If you run the statements below several times, each run creates nodes with the same name.

CREATE (j:Person {name: 'Jennifer'})-[rel:IS_FRIENDS_WITH]->
(m:Person {name: 'Mark'})

MERGE

There are some ways in Cypher to avoid creating duplicate data. One of those ways is by using the MERGE keyword. MERGE does a select-or-insert operation that first checks if the data exists in the database. If it exists, then Cypher returns it as is or makes any updates you specify on the existing node or relationship. If the data does not exist, then Cypher will create it with the information you specify.

MERGE (j:Person {name: 'Jennifer'})-[rel:IS_FRIENDS_WITH]->
(m:Person {name: 'Mark'})

It’s like a combination of MATCH and CREATE that additionally allows you to specify what happens if the data was matched or created.

Of course you want to make a difference between existing nodes or new nodes when running the MERGE command. This can be done using ON MATCH or ON CREATE.

One must be carefull, the merge command needs a full match on the specified pattern. If not, a node will be created two times.

MERGE (a:ACTOR {name:'Charlie Sheen'})
MERGE (a:ACTOR {name:'Charlie Sheen', age: '55'})

The two commands above will create TWO nodes, because the second MERGE command could not find a node with all the matching properties.

After removing all the nodes in the network, create the following nodes:

CREATE (a:ACTOR {name:'Charlie Sheen',bornin:'New York',agent:'Mike'})
CREATE (b:ACTOR {name:'Martin Sheen',bornin:'Ohio',agent:'Mike'})
CREATE (c:ACTOR {name:'Michael Douglas',bornin:'New Jersey',agent:'Nathalie'})
CREATE (d:ACTOR {name:'Oliver Stone',bornin:'New York',agent:'Annie'})

We can now create cities from the property “bornin”

MATCH (person:ACTOR)
MERGE (city:City {name: person.bornin})
RETURN person.name, person.bornIn, city

Difference between ON CREATE and ON MATCH ? Run the code below several times and see what happens !

MERGE (a:Person {name: 'Keanu Reeves'})
ON CREATE
   SET a.created = timestamp()
ON MATCH
   SET a.updated = timestamp()
RETURN a.name, a.created,a.updated

The MERGE command can also be used to create (or update) a relationship. First we can add a couple of movies to the database:

MERGE (a:Movie {title: 'Full Metal Jacket'})
MERGE (b:Movie {title: 'Apocalpys Now'})
MERGE (c:Movie {title: 'Wall Street'})
MATCH
(charlie:ACTOR {name: 'Charlie Sheen'}),
(wallStreet:Movie {title: 'Wall Street'})
MERGE (charlie)-[r:ACTED_IN]->(wallStreet)
RETURN charlie.name, type(r), wallStreet.title
MATCH
   (a:ACTOR {name: 'Oliver Stone'}),
   (b:ACTOR {name: 'Charlie Sheen'}),
   (m:Movie {title:'Wall Street'})
MERGE (a)-[:DIRECTED]->(m)<-[:ACTED_IN]-(b)
RETURN a,b

of course Oliver Stone is not an ACTOR and let’s set that straight. We change the label to DIRECTOR.

MERGE (a:ACTOR {name:'Oliver Stone'})
ON MATCH
   SET a:DIRECTOR
   REMOVE a:ACTOR
RETURN a

The same code above can be changed and specify an undirected relationship:

MATCH
   (charlie:ACTOR {name: 'Charlie Sheen'}),
   (oliver:DIRECTOR {name: 'Oliver Stone'})
MERGE (charlie)-[r:KNOWS]-(oliver)
RETURN r

MERGE can be used to simultaneously create both a new node and a new relationship.

MATCH (person)
WHERE person:ACTOR OR person:DIRECTOR
MERGE (person)-[r:HAS_AGENT]->(agent:AGENT {name: person.agent})
RETURN person.name, person.agent, agent

MERGE creates in the case above Agents and a relationship between the ACTOR,DIRECTOR nodes and the different agents.

It can be usefull to have unique properties in place for the different nodes

CREATE CONSTRAINT ON (n:ACTOR) ASSERT n.name IS UNIQUE;
CREATE CONSTRAINT ON (n:DIRECTOR) ASSERT n.name IS UNIQUE;

Creating an actor Michael Douglas who lives in Leuven will be impossible. Neo4j does not recognize the node in the MERGE statement. Because there is no match, the node will be created, but that will fail because of the unique property.

../_images/unique.png

Query

A query takes the following general form :

MATCH [node,relationship]
WHERE [Boolean condition]
RETURN [DISTINCT][statements [AS alias]]
ORDER BY [properties][ASC/DESC]
LIMIT [number]

The WHERE clause acts as a filter.

It is possible to create a node with multiple labels. Just imagine adding Mignolet as a Person and as a Goalkeeper:

CREATE (n:Person:GoalKeeper {name:'Mignolet'})

To create a relationship between two nodes, the following syntax is used:

MATCH
(a:Person),
(b:Person)
WHERE a.name = 'A' AND b.name = 'B'
CREATE (a)-[r:RELTYPE]->(b)
RETURN type(r)

We can use this to make vertongen the team-mate of Mignolet.

MATCH
(a:Person ),
(b:Person)
WHERE a.name = "Mignolet" and b.name = "Vertongen"
CREATE (a)-[ra:PLAYSWITH]->(b)
CREATE (b)-[rb:PLAYSWITH]->(a)
RETURN type(ra),type(rb)
../_images/mignolet.png

A relationship can also receive properties :

MATCH
(a:Person ),
(b:Person)
WHERE a.name = "Mignolet" and b.name = "Vertongen"
CREATE (a)-[ra:PLAYSWITH {team:"Rode Duivels"}]->(b)
CREATE (b)-[rb:PLAYSWITH {team:"Rode Duivels"}]->(a)
RETURN type(ra),type(rb)

Which result in the outcome below. What is the problem here ?

../_images/mignolet2.png

Updating Data with Cypher

Imagine one wants to modify properties. You can do this by matching the pattern you want to find and using the SET keyword to add, remove, or update properties.

MATCH (p:Person {name: 'Jennifer'})
SET p.birthdate = date('1980-01-01')
RETURN p

It is possible to change relationships

MATCH (t:Technology)
MATCH (n:Person {name: 'Jennifer'})-[rel:LIKES]-(t)
SET rel.since = 2001

Deleting Data with Cypher

For this operation, Cypher uses the DELETE keyword. You cannot delete a node if it still has relationships. Using the DETACH DELETE syntax tells Cypher to delete any relationships the node has, as well as remove the node itself.

MATCH (m:Person {name: 'Jennifer'})
DETACH DELETE m

Warning

Deleting ALL the nodes:

MATCH (n)
DETACH DELETE n

ON CREATE and ON MATCH

Perhaps you want to use MERGE to ensure you do not create duplicates, but you want to initialize certain properties if the pattern is created and update other properties if it is only matched. In this case, you can use ON CREATE or ON MATCH the SET keyword to handle these situations.

With the code below:

  • we create two nodes (if these do not yet exists)

  • add / modify a relationship’s properties

MERGE (m:Person {name: 'Wim'})-[r:WORKS_WITH]-(j:Person {name:'Peter'})
ON CREATE SET r.since = 2015
ON MATCH SET r.updated = date()

REMOVE

The remove command can be used to remove relationships, relationships properties, node properties etc…

In the example below the property componentId is removed from all the nodes with the label Person:

MATCH (node:Person)
REMOVE node.componentId
RETURN node

Last change: Oct 30, 2023