Update​
The update
command is used to update existing objects.
db> ... ...
update Hero
filter .name = "Hawkeye"
set { name := "Ronin" };
{default::Hero {id: d476b12e-3e7b-11ec-af13-2717f3dc1d8a}}
If you omit the filter
clause, all objects will be updated. This is useful
for updating values across all objects of a given type. The example below
cleans up all Hero.name
values by trimming whitespace and converting them
to title case.
db> ...
update Hero
set { name := str_trim(str_title(.name)) };
{default::Hero {id: d476b12e-3e7b-11ec-af13-2717f3dc1d8a}}
Syntax​
The structure of the update
statement (update...filter...set
) is an
intentional inversion of SQL's UPDATE...SET...WHERE
syntax. Curiously, in
SQL, the where
clauses typically occur last despite being applied before
the set
statement. EdgeQL is structured to reflect this; first, a target
set is specified, then filters are applied, then the data is updated.
Updating properties​
To explicitly unset a property that is not required, set it to an empty set.
update Person filter .id = <uuid>$id set { middle_name := {} };
Updating links​
When updating links, the :=
operator will replace the set of linked
values.
db> ... ... ... ... ... ... ...
update movie
filter .title = "Black Widow"
set {
characters := (
select Person
filter .name in { "Black Widow", "Yelena", "Dreykov" }
)
};
{default::Title {id: af706c7c-3e98-11ec-abb3-4bbf3f18a61a}}
db> ...
select Movie { num_characters := count(.characters) }
filter .title = "Black Widow";
{default::Movie {num_characters: 3}}
To add additional linked items, use the +=
operator.
db> ... ... ... ...
update Movie
filter .title = "Black Widow"
set {
characters += (insert Villain {name := "Taskmaster"})
};
{default::Title {id: af706c7c-3e98-11ec-abb3-4bbf3f18a61a}}
db> ...
select Movie { num_characters := count(.characters) }
filter .title = "Black Widow";
{default::Movie {num_characters: 4}}
To remove items, use -=
.
db> ... ... ... ...
update Movie
filter .title = "Black Widow"
set {
characters -= Villain # remove all villains
};
{default::Title {id: af706c7c-3e98-11ec-abb3-4bbf3f18a61a}}
db> ...
select Movie { num_characters := count(.characters) }
filter .title = "Black Widow";
{default::Movie {num_characters: 2}}
Returning data on update​
By default, update
returns only the inserted object's id
as seen in the
examples above. If you want to get additional data back, you may wrap your
update
with a select
and apply a shape specifying any properties and
links you want returned:
db> ... ... ...
select (update Hero
filter .name = "Hawkeye"
set { name := "Ronin" }
) {id, name};
{ default::Hero { id: d476b12e-3e7b-11ec-af13-2717f3dc1d8a, name: "Ronin" } }
With blocks​
All top-level EdgeQL statements (select
, insert
, update
, and
delete
) can be prefixed with a with
block. This is useful for updating
the results of a complex query.
db> ... ... ... ... ... ... ...
with people := (
select Person
order by .name
offset 3
limit 3
)
update people
set { name := str_trim(.name) };
{ default::Hero {id: d4764c66-3e7b-11ec-af13-df1ba5b91187}, default::Hero {id: d7d7e0f6-40ae-11ec-87b1-3f06bed494b9}, default::Villain {id: d477a836-3e7b-11ec-af13-4fea611d1c31}, }
You can pass any object-type expression into update
, including
polymorphic ones (as above).
You can also use with
to make returning additional data from an update more
readable:
db> ... ... ... ... ... ... ...
with UpdatedHero := (update Hero
filter .name = "Hawkeye"
set { name := "Ronin" }
)
select UpdatedHero {
id,
name
};
{ default::Hero { id: d476b12e-3e7b-11ec-af13-2717f3dc1d8a, name: "Ronin" } }
See also​
For documentation on performing upsert operations, see EdgeQL > Insert > Upserts.