SET#
GQL clause
Changes the properties of vertices and edges the query has bound.
Synopsis#
bold keywords · italic placeholders you supply · [ ] optional · ... repeatable. See Syntax conventions.
Description#
SET writes properties onto elements already bound by an earlier clause. The
effect depends on what is on the left of the operator and which operator you use:
Written as |
Effect |
|---|---|
|
Sets one property, adding the key if it is not there. |
|
Removes that key. |
|
Replaces the whole property bag with the map. Keys not in the map are lost. |
|
Replaces |
|
Merges the map into the bag: listed keys are set, the rest are kept. |
Assignments in one
SETare separated by commas and applied left to right.SETruns once per incoming row, so aMATCHthat finds 10 vertices updates 10 of them.SETneeds a bound variable. It cannot introduce one, and it cannot lead a query. It always follows aMATCH, aMERGEor another clause that binds something.SETmay end a query. Add aRETURNto see the result.SETwrites properties only. It cannot add or change a label.ON CREATE SETandON MATCH SETon aMERGEtake this same assignment syntax.
Parameters#
- target
A property reference,
variable.key, optionally nested asvariable.key.subkey; or a bare element variable when you are replacing or merging the whole bag.- expression
The value to store. Any Cypher expression: a literal, a property of another element, an arithmetic or
CASEexpression, a list, a map. For+=, and for=against a bare variable, it must be a map or another graph element.
Examples#
Every example runs against the example dataset. The last example undoes them.
Set one property#
CREATE (:movie {title: 'Tenet', year: 2020, genre: 'Action'});
UPDATE 1
MATCH (m:movie {title: 'Tenet'})
SET m.runtime = 150
RETURN properties(m) AS props;
props
---------------------------------------------------------------------
{"year": 2020, "genre": "Action", "title": "Tenet", "runtime": 150}
(1 row)
properties() returns the whole bag, which is the easiest way to see what a
SET did.
Set several properties in one clause#
MATCH (m:movie {title: 'Tenet'})
SET m.genre = 'Sci-Fi', m.runtime = 151
RETURN properties(m) AS props;
props
---------------------------------------------------------------------
{"year": 2020, "genre": "Sci-Fi", "title": "Tenet", "runtime": 151}
(1 row)
Remove a property with NULL#
Assigning null deletes the key rather than storing a null:
MATCH (m:movie {title: 'Tenet'})
SET m.runtime = NULL
RETURN properties(m) AS props;
props
-----------------------------------------------------
{"year": 2020, "genre": "Sci-Fi", "title": "Tenet"}
(1 row)
REMOVE says the same thing more plainly.
Merge a map with +=#
+= sets the keys the map lists and leaves the others alone:
MATCH (m:movie {title: 'Tenet'})
SET m += {runtime: 150, imax: true}
RETURN properties(m) AS props;
props
-----------------------------------------------------------------------------------
{"imax": true, "year": 2020, "genre": "Sci-Fi", "title": "Tenet", "runtime": 150}
(1 row)
Replace the whole bag with =#
= against a bare variable throws away everything not in the map. genre,
runtime and imax are gone:
MATCH (m:movie {title: 'Tenet'})
SET m = {title: 'Tenet', year: 2020}
RETURN properties(m) AS props;
props
----------------------------------
{"year": 2020, "title": "Tenet"}
(1 row)
This is the difference between the two operators, and the one to be careful
about: = is a replacement, += is an update.
Copy one element’s properties to another#
The right-hand side can be another element, which copies its whole bag:
CREATE (:person {name: 'Stand-in'});
UPDATE 1
MATCH (p:person {name: 'Stand-in'}), (k:person {name: 'Keanu Reeves'})
SET p = k
RETURN properties(p) AS props;
props
----------------------------------------
{"born": 1964, "name": "Keanu Reeves"}
(1 row)
There are now two vertices whose name is Keanu Reeves:
MATCH (p:person {name: 'Keanu Reeves'}) RETURN count(*) AS keanus;
keanus
--------
2
(1 row)
Copying a bag copies the identifying properties too. It does not copy edges, and it does not merge the two vertices.
Set a property on an edge#
An edge takes properties exactly as a vertex does:
MATCH (:person {name: 'Keanu Reeves'})-[r:acted_in]->(:movie {title: 'The Matrix'})
SET r.credited = true
RETURN properties(r) AS props;
props
-----------------------------------
{"role": "Neo", "credited": true}
(1 row)
MATCH (:person {name: 'Keanu Reeves'})-[r:acted_in]->(:movie {title: 'The Matrix'})
SET r.credited = NULL
RETURN properties(r) AS props;
props
-----------------
{"role": "Neo"}
(1 row)
The MATCH finds the one edge that belongs to the original Keanu Reeves, because
the copy created above has no edges.
Empty a bag#
An empty map removes every property, leaving the element in place:
MATCH (m:movie {title: 'Tenet'})
SET m = {}
RETURN properties(m) AS props;
props
-------
{}
(1 row)
The vertex is now unreachable by any property. The cleanup below therefore looks
for a missing title rather than for Tenet.
Undo the examples#
MATCH (m:movie) WHERE m.title IS NULL DETACH DELETE m;
MATCH (p:person) WHERE p.name = 'Keanu Reeves' AND NOT EXISTS { MATCH (p)-[]->() } DETACH DELETE p;
UPDATE 1
UPDATE 1
Notes#
The default setting allow_null_properties = off makes SET n.key = NULL a
deletion. Turn it on and the key is kept with a JSON null value instead:
SET allow_null_properties = true;
CREATE (m:movie {title: 'Tenet', year: 2020})
SET m.runtime = NULL
RETURN properties(m) AS props;
SET
props
---------------------------------------------------
{"year": 2020, "title": "Tenet", "runtime": null}
(1 row)
SET allow_null_properties = false;
MATCH (m:movie {title: 'Tenet'}) DETACH DELETE m;
SET
UPDATE 1
A stored null is not the same as an absent key: m.runtime IS NULL is true
either way, but the key shows up in properties() and in a jsonb key test.
Compatibility#
Setting a label (ISO/IEC 39075 §13.3)#
The standard’s <set label item> adds a label to an element, written
SET n:blockbuster or SET n IS blockbuster. AgensGraph accepts neither:
MATCH (m:movie {title: 'Inception'}) SET m:blockbuster RETURN m.title;
ERROR: syntax error at or near ":"
LINE 1: MATCH (m:movie {title: 'Inception'}) SET m:blockbuster RETUR...
^
An element’s label is the table it lives in, so it is fixed when the element is created. To move a vertex to another label, create it there and delete the original.