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:

[width="500"

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:

Query
MATCH (n {name: 'Andy'})
SET n.surname = 'Taylor'
RETURN n.name, n.surname

The newly-changed node is returned by the query.

Table 1. Result
n.name n.surname

"Andy"

"Taylor"

Rows: 1
Properties set: 1

Update a relationship property:

Query
MATCH (n:Swedish {name: 'Andy'})-[r:KNOWS]->(m)
SET r.since = 1999
RETURN r, m.name AS friend
Table 2. Result
r friend

[:KNOWS {since: 1999}]

"Peter"

Rows: 1
Properties set: 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:

Query
MATCH (n {name: 'Andy'})
SET (CASE WHEN n.age = 36 THEN n END).worksIn = 'Malmo'
RETURN n.name, n.worksIn
Table 3. Result
n.name n.worksIn

"Andy"

"Malmo"

Rows: 1
Properties set: 1

No action will be taken if the node expression evaluates to null, as shown in this example:

Query
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.

Table 4. Result
n.name n.worksIn

"Andy"

<null>

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:

Query
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'.

Table 5. Result
n.name n.age

"Andy"

"36"

Rows: 1
Properties set: 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:

Query
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.

Table 6. Result
n.name keys(n)

"Andy"

["name", "nameCopy", "age", "ageCopy", "hungry", "hungryCopy"]

"Stefan"

["name", "nameCopy"]

"Peter"

["name", "nameCopy", "age", "ageCopy"]

"George"

["name", "nameCopy"]

Rows: 4
Properties set: 6

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.

Query
MATCH (n {name: 'Andy'})
SET n.name = null
RETURN n.name, n.age

The name property is now missing.

Table 7. Result
n.name n.age

<null>

"36"

Rows: 1
Properties set: 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.

Query
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.

Table 8. Result
at.name at.age at.hungry pn.name pn.age

"Peter"

34

<null>

"Peter"

34

Rows: 1
Properties set: 3

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:

Query
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.

Table 9. Result
p.name p.age p.position

"Peter Smith"

<null>

"Entrepreneur"

Rows: 1
Properties set: 3

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:

Query
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.

Table 10. Result
p.name p.age

<null>

<null>

Rows: 1
Properties set: 2

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.

Query
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.

Table 11. Result
p.name p.age p.hungry p.position

"Peter"

38

true

"Entrepreneur"

Rows: 1
Properties set: 3

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:

Query
MATCH (p {name: 'Peter'})
SET p += {}
RETURN p.name, p.age
Table 12. Result
p.name p.age

"Peter"

34

Rows: 1

Set multiple properties using one SET clause

Set multiple properties at once by separating them with a comma:

Query
MATCH (n {name: 'Andy'})
SET n.position = 'Developer', n.surname = 'Taylor'
Table 13. Result

(empty result)

Rows: 0
Properties set: 2

Set a property using a parameter

Use a parameter to set the value of a property:

Parameters
{
  "surname": "Taylor"
}
Query
MATCH (n {name: 'Andy'})
SET n.surname = $surname
RETURN n.name, n.surname

A surname property has been added to the 'Andy' node.

Table 14. Result
n.name n.surname

"Andy"

"Taylor"

Rows: 1
Properties set: 1

Set all properties using a parameter

This will replace all existing properties on the node with the new set provided by the parameter.

Parameters
{
  "props" : {
    "name": "Andy",
    "position": "Developer"
  }
}
Query
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.

Table 15. Result
n.name n.position n.age n.hungry

"Andy"

"Developer"

<null>

<null>

Rows: 1
Properties set: 4

Set a label on a node

Use SET to set a label on a node:

Query
MATCH (n {name: 'Stefan'})
SET n:German
RETURN n.name, labels(n) AS labels

The newly-labeled node is returned by the query.

Table 16. Result
n.name labels

"Stefan"

["German"]

Rows: 1
Labels added: 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>)
Query
MATCH (n:Swedish)
SET n:$(n.name)
RETURN n.name, labels(n) AS labels

The newly-labeled node is returned by the query.

Table 17. Result
n.name labels

"Andy"

["Swedish", "Andy"]

Rows: 1
Labels added: 1

Set a label using a parameter

Use a parameter to set the value of a label:

Parameters
{
  "label": "Danish"
}
Query
MATCH (n {name: 'Stefan'})
SET n:$($label)
RETURN labels(n) AS labels

A Danish label has been added to the 'Stefan' node.

Table 18. Result
labels

['German', 'Danish']

Rows: 1
Labels added: 1

Set multiple labels on a node

Set multiple labels on a node with SET and use : to separate the different labels:

Query
MATCH (n {name: 'George'})
SET n:Swedish:Bossman
RETURN n.name, labels(n) AS labels

The newly-labeled node is returned by the query.

Table 19. Result
n.name labels

"George"

["Swedish","Bossman"]

Rows: 1
Labels added: 2

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 ::

Query
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.

Table 20. Result
n.name labels

"George"

["Swedish","Bossman", "Label0", "Label1", "Label2", "Label3"]

Rows: 1
Labels added: 4

Set multiple labels using parameters

Use a parameter to set multiple labels:

Parameters
{
  "labels": ["Swedish", "German"]
}
Query
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.

Table 21. Result
labels

['Swedish', 'German']

Rows: 1
Labels added: 2