Skip to main content
Version: 1.x

UPDATE statement

The UPDATE statement can be used to update or modify records in the database.

Note: This statement can not be used to create graph relationships. For that, use the RELATE statement.

Statement syntax

SurrealQL Syntax
UPDATE [ ONLY ] @targets
[ CONTENT @value
| MERGE @value
| PATCH @value
| [ SET @field = @value, ... | UNSET @field, ... ]
]
[ WHERE @condition ]
[ RETURN NONE | RETURN BEFORE | RETURN AFTER | RETURN DIFF | RETURN @statement_param, ... ]
[ TIMEOUT @duration ]
[ PARALLEL ]
;

@target refers to either record output including an id field, or a record ID on its own.

Example usage

The following query shows example usage of this statement.

-- Update all records in a table
-- The skills field is an array. The += operator alone is enough for SurrealDB to infer the type
UPDATE person SET skills += 'breathing';

-- Update or create a record with a specific numeric id
UPDATE person:100 SET name = 'Tobie', company = 'SurrealDB', skills = ['Rust', 'Go', 'JavaScript'];

-- Update or create a record with a specific string id
UPDATE person:tobie SET name = 'Tobie', company = 'SurrealDB', skills = ['Rust', 'Go', 'JavaScript'];

-- Update just a single record
-- Using the ONLY keyword, just an object for the record in question will be returned.
-- This, instead of an array with a single object.
UPDATE ONLY person:tobie SET name = 'Tobie', company = 'SurrealDB', skills = ['Rust', 'Go', 'JavaScript'];

When specifying fields to update using the SET clause, it is possible to increment and decrement numeric values, and add or remove values from arrays. To increment a numeric value, or to add an item to an array, use the += operator. To decrement a numeric value, or to remove a value from an array, use the -= operator.

-- Update a document and increment a numeric value
UPDATE webpage:home SET click_count += 1;

-- Update a document and remove a tag from an array
UPDATE person:tobie SET interests -= 'Java';

-- Remove a field by setting it to NONE or using the UNSET keyword
UPDATE webpage:home SET click_count = NONE;

UPDATE user:one UNSET email, address;

The update statement supports conditional matching of records using a WHERE clause. If the expression in the WHERE clause evaluates to true, then the respective record will be updated.

-- Update all records which match the condition
UPDATE city SET population = 9541000 WHERE name = 'London';

Instead of specifying record data using the SET clause, it is also possible to use the CONTENT keyword to specify the record data using a SurrealQL object.

-- Update all records with the same content
UPDATE person CONTENT {
name: 'Tobie',
company: 'SurrealDB',
skills: ['Rust', 'Go', 'JavaScript'],
};

-- Update a specific record with some content
UPDATE person:tobie CONTENT {
name: 'Tobie',
company: 'SurrealDB',
skills: ['Rust', 'Go', 'JavaScript'],
};

Instead of specifying the full record data using the SET clause or the CONTENT keyword, it is also possible to merge-update only specific fields by using the MERGE keyword and specifying only the fields which are to be updated.

-- Update certain fields on all records
UPDATE person MERGE {
settings: {
marketing: true,
},
};

-- Update certain fields on a specific record
UPDATE person:tobie MERGE {
settings: {
marketing: true,
},
};

You can also specify changes to be applied to your query response, using the PATCH command which works similar to the JSON Patch specification

-- Patch the JSON response
UPDATE person:tobie PATCH [
{
"op": "add",
"path": "Engineering",
"value": "true"
}
]

By default, the update statement returns the record value once the changes have been made. To change the return value of each record, specify a RETURN clause, specifying either NONE, BEFORE, AFTER, DIFF, or a comma-separated list of specific fields to return.

-- Don't return any result
UPDATE person SET interests += 'reading' RETURN NONE;

-- Return the changeset diff
UPDATE person SET interests += 'reading' RETURN DIFF;

-- Return the record before changes were applied
UPDATE person SET interests += 'reading' RETURN BEFORE;

-- Return the record after changes were applied (the default)
UPDATE person SET interests += 'reading' RETURN AFTER;

-- Return a specific field only from the updated records
UPDATE person:tobie SET interests = ['skiing', 'music'] RETURN name, interests;

An UPDATE statement will work on any value as long as it is a record ID, or if it contains an id field which is a record ID:

CREATE person SET name = 'Tobie';
// A single id works: $tobie will now look something like person:qz8mnqmuzs2w6emdn08q
LET $tobie = SELECT VALUE id FROM ONLY person WHERE name = 'Tobie' LIMIT 1;
UPDATE $tobie SET skills += 'breathing';

CREATE person SET name = 'Jaime';
// An entire record also works:
// $jaime will look something like { id: person:y5o8pf1hkerlhdzf7jyb, name: 'Jaime' }
LET $jaime = SELECT * FROM ONLY person WHERE name = 'Jaime' LIMIT 1;
UPDATE $jaime SET skills += 'breathing';

CREATE person SET name = 'Uther';
// But a record without an id field will not work
LET $uther = SELECT name FROM ONLY person WHERE name = 'Uther' LIMIT 1;
// Error: "Can not execute UPDATE statement using value '{ name: 'Uther' }'"
UPDATE $uther SET skills += 'breathing';

When processing a large result set with many interconnected records, it is possible to use the TIMEOUT keywords to specify a timeout duration for the statement. If the statement continues beyond this duration, then the transaction will fail, no records will be updated in the database, and the statement will return an error.

UPDATE person SET important = true WHERE ->knows->person->(knows WHERE influencer = true) TIMEOUT 5s;