@@ -3,10 +3,16 @@ title: '`UPSERT` operation in AQL'
33menuTitle : UPSERT
44weight : 70
55description : >-
6- The `UPSERT` operations either modifies an existing document, or creates a new
6+ An `UPSERT` operation either modifies an existing document, or creates a new
77 document if it does not exist
88archetype : default
99---
10+ ` UPSERT ` looks up a single document that matches the provided example.
11+ If there is no match, an insert operation is executed to create a
12+ document. If a document is found, you can either update or replace the document.
13+ These subtypes are called ** upsert** (update or insert) and ** repsert**
14+ (replace or insert).
15+
1016Each ` UPSERT ` operation is restricted to a single collection, and the
1117[ collection name] ( ../../concepts/data-structure/collections.md#collection-names ) must not be dynamic.
1218Only a single ` UPSERT ` statement per collection is allowed per AQL query, and
@@ -15,44 +21,47 @@ traversal operations, or AQL functions that can read documents.
1521
1622## Syntax
1723
18- The syntax for upsert and repsert operations is :
24+ The syntax for an upsert operation :
1925
2026<pre ><code >UPSERT <em >searchExpression</em >
2127INSERT <em >insertExpression</em >
2228UPDATE <em >updateExpression</em >
2329IN <em >collection</em ></code ></pre >
2430
31+ The syntax for a repsert operation:
32+
2533<pre ><code >UPSERT <em >searchExpression</em >
2634INSERT <em >insertExpression</em >
2735REPLACE <em >updateExpression</em >
2836IN <em >collection</em ></code ></pre >
2937
3038Both variants can optionally end with an ` OPTIONS { … } ` clause.
3139
32- When using the ` UPDATE ` variant of the upsert operation, the found document
33- will be partially updated, meaning only the attributes specified in
34- * updateExpression* will be updated or added. When using the ` REPLACE ` variant
35- of upsert (repsert), existing documents will be replaced with the contexts of
40+ When using the ` UPDATE ` variant of the ` UPSERT ` operation, the found document
41+ is partially updated, meaning only the attributes specified in
42+ * updateExpression* are updated or added. When using the ` REPLACE ` variant
43+ of ` UPSERT ` (repsert), the found document is replaced with the content of
3644* updateExpression* .
3745
38- Updating a document will modify the document's revision number with a server-generated value.
39- The system attributes ` _id ` , ` _key ` and ` _rev ` cannot be updated, ` _from ` and ` _to ` can.
46+ Updating a document modifies the document's revision number with a server-generated value.
47+ The system attributes ` _id ` , ` _key ` , and ` _rev ` cannot be updated, but ` _from ` and ` _to `
48+ can be modified.
4049
41- The * searchExpression* contains the document to be looked for. It must be an object
42- literal without dynamic attribute names. In case no such document can be found in
43- * collection * , a new document will be inserted into the collection as specified in the
44- * insertExpression* .
50+ The * searchExpression* contains the document to be looked for. It must be an
51+ ** object literal** ( ` UPSERT { <key>: <value>, ... } ... ` ) without dynamic
52+ attribute names. In case no such document can be found in * collection* , a new
53+ document is inserted into the collection as specified in the * insertExpression* .
4554
46- In case at least one document in * collection* matches the * searchExpression* , it will
47- be updated using the * updateExpression* . When more than one document in the collection
48- matches the * searchExpression* , it is undefined which of the matching documents will
49- be updated. It is therefore often sensible to make sure by other means (such as unique
55+ In case at least one document in * collection* matches the * searchExpression* , it is
56+ updated using the * updateExpression* . When more than one document in the collection
57+ matches the * searchExpression* , it is undefined which of the matching documents is
58+ updated. It is therefore often sensible to make sure by other means (such as unique
5059indexes, application logic etc.) that at most one document matches * searchExpression* .
5160
52- The following query will look in the * users* collection for a document with a specific
53- * name* attribute value. If the document exists, its * logins* attribute will be increased
54- by one. If it does not exist, a new document will be inserted, consisting of the
55- attributes * name* , * logins* , and * dateCreated* :
61+ The following query looks for a document in the ` users ` collection with a specific
62+ ` name ` attribute value. If the document exists, its * logins* attribute is increased
63+ by one. If it does not exist, a new document is inserted, consisting of the
64+ attributes ` name ` , ` logins ` , and ` dateCreated ` :
5665
5766``` aql
5867UPSERT { name: 'superuser' }
@@ -96,7 +105,7 @@ inside of arrays (e.g. `{ attr: [ { nested: null } ] }`).
96105
97106### ` mergeObjects `
98107
99- The option ` mergeObjects ` controls whether object contents will be
108+ The option ` mergeObjects ` controls whether object contents are
100109merged if an object attribute is present in both the ` UPDATE ` query and in the
101110to-be-updated document.
102111
@@ -125,9 +134,9 @@ FOR i IN 1..1000
125134```
126135
127136{{< info >}}
128- You need to add the ` _rev ` value in the * updateExpression* . It will not be used
137+ You need to add the ` _rev ` value in the * updateExpression* . It is not used
129138within the * searchExpression* . Even worse, if you use an outdated ` _rev ` in the
130- * searchExpression* , ` UPSERT ` will trigger the ` INSERT ` path instead of the
139+ * searchExpression* , ` UPSERT ` triggers the ` INSERT ` path instead of the
131140` UPDATE ` path, because it has not found a document exactly matching the
132141* searchExpression* .
133142{{< /info >}}
@@ -153,7 +162,7 @@ FOR i IN 1..1000
153162
154163### ` indexHint `
155164
156- The ` indexHint ` option will be used as a hint for the document lookup
165+ The ` indexHint ` option is used as a hint for the document lookup
157166performed as part of the ` UPSERT ` operation, and can help in cases such as
158167` UPSERT ` not picking the best index automatically.
159168
@@ -167,6 +176,8 @@ UPSERT { a: 1234 }
167176The index hint is passed through to an internal ` FOR ` loop that is used for the
168177lookup. Also see [ ` indexHint ` Option of the ` FOR ` Operation] ( for.md#indexhint ) .
169178
179+ Inverted indexes cannot be used for ` UPSERT ` lookups.
180+
170181### ` forceIndexHint `
171182
172183Makes the index or indexes specified in ` indexHint ` mandatory if enabled. The
@@ -185,11 +196,11 @@ UPSERT { a: 1234 }
185196` UPSERT ` statements can optionally return data. To do so, they need to be followed
186197by a ` RETURN ` statement (intermediate ` LET ` statements are allowed, too). These statements
187198can optionally perform calculations and refer to the pseudo-values ` OLD ` and ` NEW ` .
188- In case the upsert performed an insert operation, ` OLD ` will have a value of ` null ` .
189- In case the upsert performed an update or replace operation, ` OLD ` will contain the
199+ In case the upsert performed an insert operation, ` OLD ` has a value of ` null ` .
200+ In case the upsert performed an update or replace operation, ` OLD ` contains the
190201previous version of the document, before update/replace.
191202
192- ` NEW ` will always be populated. It will contain the inserted document in case the
203+ ` NEW ` is always populated. It contains the inserted document in case the
193204upsert performed an insert, or the updated/replaced document in case it performed an
194205update/replace.
195206
0 commit comments