SET
The SET
clause is used to update labels on nodes and properties on nodes and relationships.
The SET
clause can be used with a map — provided as a literal or a parameter — to set properties.
Setting labels on a node is an idempotent operation — nothing will occur if an attempt is made to set a label on a node that already has that label. The query statistics will state whether any updates actually took place. |
Example graph
The following graph is used for the examples below:
To recreate it, run the following query against an empty Neo4j database:
CREATE
(a:Swedish {name: 'Andy', age: 36, hungry: true}),
(b {name: 'Stefan'}),
(c {name: 'Peter', age: 34}),
(d {name: 'George'}),
(a)-[:KNOWS]->(c),
(b)-[:KNOWS]->(a),
(d)-[:KNOWS]->(c)
Set a property
Update a node property:
MATCH (n {name: 'Andy'})
SET n.surname = 'Taylor'
RETURN n.name, n.surname
The newly-changed node is returned by the query.
n.name | n.surname |
---|---|
|
|
Rows: 1 |
Update a relationship property:
MATCH (n:Swedish {name: 'Andy'})-[r:KNOWS]->(m)
SET r.since = 1999
RETURN r, m.name AS friend
r | friend |
---|---|
|
|
Rows: 1 |
It is possible to set a property on a node or relationship using more complex expressions. For instance, in contrast to specifying the node directly, the following query shows how to set a property for a node selected by an expression:
MATCH (n {name: 'Andy'})
SET (CASE WHEN n.age = 36 THEN n END).worksIn = 'Malmo'
RETURN n.name, n.worksIn
n.name | n.worksIn |
---|---|
|
|
Rows: 1 |
No action will be taken if the node expression evaluates to null
, as shown in this example:
MATCH (n {name: 'Andy'})
SET (CASE WHEN n.age = 55 THEN n END).worksIn = 'Malmo'
RETURN n.name, n.worksIn
As no node matches the CASE
expression, the expression returns a null
.
As a consequence, no updates occur, and therefore no worksIn
property is set.
n.name | n.worksIn |
---|---|
|
|
Rows: 1 |
Update a property
SET
can be used to update a property on a node or relationship.
This query forces a change of type in the age
property:
MATCH (n {name: 'Andy'})
SET n.age = toString(n.age)
RETURN n.name, n.age
The age
property has been converted to the STRING
'36'
.
n.name | n.age |
---|---|
|
|
Rows: 1 |
Dynamically set or update a property
SET
can be used to set or update a property on a node or relationship even when the property key name is not statically known.
This allows for more flexible queries and mitigates the risk of Cypher® injection.
(For more information about Cypher injection, see Neo4j Knowledge Base → Protecting against Cypher injection).
SET n[key] = expression
The dynamically calculated key must evaluate to a STRING
value.
This query creates a copy of every property on the nodes:
MATCH (n)
FOREACH (k IN keys(n) | SET n[k + "Copy"] = n[k]) (1)
RETURN n.name, keys(n);
1 | The FOREACH clause iterates over each property key k obtained from the keys() function.
For each key, it sets a new property on the nodes with a key name of k + "Copy" and copies the value from the original property. |
The nodes now have copies of all their properties.
n.name | keys(n) |
---|---|
|
|
|
|
|
|
|
|
Rows: 4 |
Remove a property
Although REMOVE
is normally used to remove a property, it is sometimes convenient to do it using the SET
command.
A case in point is if the property is provided by a parameter.
MATCH (n {name: 'Andy'})
SET n.name = null
RETURN n.name, n.age
The name
property is now missing.
n.name | n.age |
---|---|
|
|
Rows: 1 |
Copy properties between nodes and relationships
SET
can be used to copy all properties from one node or relationship to another using the properties()
function.
This will remove all other properties on the node or relationship being copied to.
MATCH
(at {name: 'Andy'}),
(pn {name: 'Peter'})
SET at = properties(pn)
RETURN at.name, at.age, at.hungry, pn.name, pn.age
The 'Andy'
node has had all its properties replaced by the properties of the 'Peter'
node.
at.name | at.age | at.hungry | pn.name | pn.age |
---|---|---|---|---|
|
|
|
|
|
Rows: 1 |
Replace all properties using a map and =
The property replacement operator =
can be used with SET
to replace all existing properties on a node or relationship with those provided by a map:
MATCH (p {name: 'Peter'})
SET p = {name: 'Peter Smith', position: 'Entrepreneur'}
RETURN p.name, p.age, p.position
This query updated the name
property from Peter
to Peter Smith
, deleted the age
property, and added the position
property to the 'Peter'
node.
p.name | p.age | p.position |
---|---|---|
|
|
|
Rows: 1 |
Remove all properties using an empty map and =
All existing properties can be removed from a node or relationship by using SET
with =
and an empty map as the right operand:
MATCH (p {name: 'Peter'})
SET p = {}
RETURN p.name, p.age
This query removed all the existing properties — namely, name
and age
— from the 'Peter'
node.
p.name | p.age |
---|---|
|
|
Rows: 1 |
Mutate specific properties using a map and +=
The property mutation operator +=
can be used with SET
to mutate properties from a map in a fine-grained fashion:
-
Any properties in the map that are not on the node or relationship will be added.
-
Any properties not in the map that are on the node or relationship will be left as is.
-
Any properties that are in both the map and the node or relationship will be replaced in the node or relationship. However, if any property in the map is
null
, it will be removed from the node or relationship.
MATCH (p {name: 'Peter'})
SET p += {age: 38, hungry: true, position: 'Entrepreneur'}
RETURN p.name, p.age, p.hungry, p.position
This query left the name
property unchanged, updated the age
property from 34
to 38
, and added the hungry
and position
properties to the 'Peter'
node.
p.name | p.age | p.hungry | p.position |
---|---|---|---|
|
|
|
|
Rows: 1 |
In contrast to the property replacement operator =
, providing an empty map as the right operand to +=
will not remove any existing properties from a node or relationship.
In line with the semantics detailed above, passing in an empty map with +=
will have no effect:
MATCH (p {name: 'Peter'})
SET p += {}
RETURN p.name, p.age
p.name | p.age |
---|---|
|
|
Rows: 1 |
Set multiple properties using one SET
clause
Set multiple properties at once by separating them with a comma:
MATCH (n {name: 'Andy'})
SET n.position = 'Developer', n.surname = 'Taylor'
|
Rows: 0 |
Set a property using a parameter
Use a parameter to set the value of a property:
{
"surname": "Taylor"
}
MATCH (n {name: 'Andy'})
SET n.surname = $surname
RETURN n.name, n.surname
A surname
property has been added to the 'Andy'
node.
n.name | n.surname |
---|---|
|
|
Rows: 1 |
Set all properties using a parameter
This will replace all existing properties on the node with the new set provided by the parameter.
{
"props" : {
"name": "Andy",
"position": "Developer"
}
}
MATCH (n {name: 'Andy'})
SET n = $props
RETURN n.name, n.position, n.age, n.hungry
The 'Andy'
node has had all its properties replaced by the properties in the props
parameter.
n.name | n.position | n.age | n.hungry |
---|---|---|---|
|
|
|
|
Rows: 1 |
Set a label on a node
Use SET
to set a label on a node:
MATCH (n {name: 'Stefan'})
SET n:German
RETURN n.name, labels(n) AS labels
The newly-labeled node is returned by the query.
n.name | labels |
---|---|
|
|
Rows: 1 |
Dynamically set a node label
SET
can be used to set a label on a node even when the label is not statically known.
MATCH (n)
SET n:$(<expr>)
MATCH (n:Swedish)
SET n:$(n.name)
RETURN n.name, labels(n) AS labels
The newly-labeled node is returned by the query.
n.name | labels |
---|---|
|
|
Rows: 1 |
Set a label using a parameter
Use a parameter to set the value of a label:
{
"label": "Danish"
}
MATCH (n {name: 'Stefan'})
SET n:$($label)
RETURN labels(n) AS labels
A Danish
label has been added to the 'Stefan'
node.
labels |
---|
|
Rows: 1 |
Set multiple labels on a node
Set multiple labels on a node with SET
and use :
to separate the different labels:
MATCH (n {name: 'George'})
SET n:Swedish:Bossman
RETURN n.name, labels(n) AS labels
The newly-labeled node is returned by the query.
n.name | labels |
---|---|
|
|
Rows: 1 |
Set multiple labels dynamically on a node
It is possible to set multiple labels dynamically using a LIST<STRING>
and/or by chaining them separately with a :
:
WITH COLLECT { UNWIND range(0,3) AS id RETURN "Label" + id } as labels (1)
MATCH (n {name: 'George'})
SET n:$(labels)
RETURN n.name, labels(n) AS labels
1 | A COLLECT subquery aggregates the results of UNWIND range(0,3) AS id RETURN "Label" + id , which generates a LIST<STRING> strings ("Label0", "Label1", "Label2", "Label3"), and assigns it to the variable labels . |
The newly-labeled node is returned by the query.
n.name | labels |
---|---|
|
|
Rows: 1 |
Set multiple labels using parameters
Use a parameter to set multiple labels:
{
"labels": ["Swedish", "German"]
}
MATCH (n {name: 'Peter'})
SET n:$($labels)
RETURN labels(n) AS labels
A Swedish
and a German
label has been added to the 'Peter'
node.
labels |
---|
|
Rows: 1 |