diff --git a/src/content/doc-surrealql/statements/upsert.mdx b/src/content/doc-surrealql/statements/upsert.mdx
index d9178a93f..b161ba10f 100644
--- a/src/content/doc-surrealql/statements/upsert.mdx
+++ b/src/content/doc-surrealql/statements/upsert.mdx
@@ -10,10 +10,9 @@ import Since from '@components/Since.astro'
-The `UPSERT` statement can be used to modify records in the database if they already exist. If the record does not exist, it will be created.
-
-This is different from the [`UPDATE`](/docs/surrealql/statements/update) statement, which will fail if the record does not exist.
+The `UPSERT` statement can be used to modify records in the database if they already exist. If a specified record ID does not exist, it will be created.
+This is different from the [`UPDATE`](/docs/surrealql/statements/update) statement, which will do nothing if a specified record ID does not exist.
### Statement syntax
@@ -22,7 +21,7 @@ UPSERT [ ONLY ] @targets
[ CONTENT @value
| MERGE @value
| PATCH @value
- | SET @field = @value ...
+ | [ SET @field = @value, ... | UNSET @field, ... ]
]
[ WHERE @condition ]
[ RETURN NONE | RETURN BEFORE | RETURN AFTER | RETURN DIFF | RETURN @statement_param, ... ]
@@ -30,56 +29,105 @@ UPSERT [ ONLY ] @targets
[ PARALLEL ]
;
```
+
## Example usage
-For example, if you want to UPSERT a record if it exists, or create it if it does not, you can use the `UPSERT` statement.
+If you want to update a record if it exists, or create it if it does not, you can use the `UPSERT` statement with a specific record ID.
```surql
--- UPSERT or create a record with a specific numeric id
-UPSERT person:100 SET name = 'Tobie', company = 'SurrealDB', skills = ['Rust', 'Go', 'JavaScript'];
+-- Update or create a record with a specific numeric id
+UPSERT person:100 SET
+ name = 'Tobie',
+ company = 'SurrealDB',
+ skills = ['Rust', 'Go', 'JavaScript'];
```
-The `UPSERT` statement can be used to modify records in the database if they already exist. If the record does not exist, it will be created.
-In the case where the record ID isn't specified, any exisiting records in the table will be upserted. For example, the following query will UPSERT all records in the `person` table:
+In the case where the record ID isn't specified, any existing records in the table will be updated. For example, the following query will update all records in the `person` table but will not create any new ones.
```surql
-- UPSERT all records in a table
-- The skills field is an array. The += operator alone is enough for SurrealDB to infer the type
-UPSERT person SET skills += 'breathing';
-```
-
-The `UPSERT` statement supports conditional matching using the `WHERE` clause. For example, the following query will upsert the record with the specified ID only if the `name` field is equal to 'Tobie':
-
-```surql
--- UPSERT a record with a specific numeric id only if the name is 'Tobie'
-UPSERT person:100 SET name = 'Tobie', company = 'SurrealDB', skills = ['Rust', 'Go', 'JavaScript'] WHERE name = 'Tobie';
+UPSERT person SET skills -= 'breathing';
```
## Using ONLY clause
+The `ONLY` clause can be used to return a single record instead of an array of records.
+
```surql
-- UPSERT 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.
-UPSERT ONLY person:tobie SET name = 'Tobie', company = 'SurrealDB', skills = ['Rust', 'Go', 'JavaScript'];
+UPSERT ONLY person:tobie SET
+ name = 'Tobie',
+ company = 'SurrealDB',
+ skills = ['Rust', 'Go', 'JavaScript'];
+```
+
+## Type inference when using UPSERT
+
+The `+=` operator in the following query is enough for SurrealDB to infer that the `interests` field must be an `array`.
+
+```surql
+-- UPSERT a document and remove a tag from an array
+UPSERT person:tobie SET interests += 'Java';
```
+Type inference will also work with a numeric value such as the `click_count` field below, in which case it will infer the field to be of type `int` with a default value of 0.
```surql
-- UPSERT a document and increment a numeric value
UPSERT webpage:home SET click_count += 1;
+```
--- UPSERT a document and remove a tag from an array
-UPSERT person:tobie SET interests -= 'Java';
+Creating a record by default makes the `UPSERT` statement an ideal way to manage an incrementing field.
+
+```surql
+UPSERT event_for:[time::now().format("%Y-%m-%d")] SET
+ number += 1;
```
+
+```bash title="Possible output"
+[
+ {
+ id: event_for:[
+ '2024-09-18'
+ ],
+ number: 1
+ }
+]
+```
+
+Doing the same with an `UPDATE` statement would require much more manual work.
+
+```surql
+IF (SELECT * FROM event_for:[time::now().format("%Y-%m-%d")]).is_empty() {
+ CREATE event_for:[time::now().format("%Y-%m-%d")] SET number = 1;
+} ELSE {
+ UPDATE event_for:[time::now().format("%Y-%m-%d")] SET number += 1;
+};
+```
+
## Using WHERE clause
-The `UPSERT` 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 upserted.
+The `UPSERT` statement supports conditional matching using the `WHERE` clause, effectively turning it into an `UPDATE` statement. For example, the following query will update the record with the specified ID only if the `name` field is equal to 'Tobie' and will not create it otherwise.
+
+```surql
+-- UPSERT a record with a specific numeric id only if the name is 'Tobie'
+UPSERT person:100 SET
+ name = 'Tobie',
+ company = 'SurrealDB',
+ skills = ['Rust', 'Go', 'JavaScript']
+WHERE name = 'Tobie';
+```
```surql
-- UPSERT all records which match the condition
UPSERT city SET population = 9541000 WHERE name = 'London';
```
+
+## CONTENT clause
+
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.
```surql
@@ -141,7 +189,7 @@ The `UPSERT` statement supports bulk upsert, which allows multiple records to be
UPSERT person CONTENT [
{id: r"person:jaime", name: "Jaime", surname: "Morgan Hitchcock"},
{id: "tobie", name: "Tobie", surname: "Morgan Hitchcock"},
- ... 1000 more records
+ -- ... 1000 more records
]
```