Skip to content

DOC-614 | Versioning support for document operations #453

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions site/content/3.12/aql/high-level-operations/replace.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,18 @@ REPLACE { _key: "123", _from: "vert/C", _to: "vert/D" } IN edgeColl
OPTIONS { refillIndexCaches: true }
```

### `versionAttribute`

The optional `versionAttribute` can be used for external versioning
support. If set, the attribute with the name specified by the option is
looked up in the document to be replaced and its content is read and compared numerically to the value of
the versioning attribute in the document that replaces it.
If the version number in the new document is higher than in the document that
already exists in the database, then the operation is performed normally.
If the version number in the new document is lower or equal to what exists in
the database, the operation is not performed and behaves like a no-op. No error
is returned in this case.

## Returning the modified documents

You can optionally return the documents modified by the query. In this case, the `REPLACE`
Expand Down
12 changes: 12 additions & 0 deletions site/content/3.12/aql/high-level-operations/update.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,18 @@ UPDATE { _key: "123", _from: "vert/C", _to: "vert/D" } IN edgeColl
OPTIONS { refillIndexCaches: true }
```

### `versionAttribute`

The optional `versionAttribute` can be used for external versioning
support. If set, the attribute with the name specified by the option is
looked up in the document to be updated and its content is read and compared numerically to the value of
the versioning attribute in the document that updates it.
If the version number in the new document is higher than in the document that
already exists in the database, then the operation is performed normally.
If the version number in the new document is lower or equal to what exists in
the database, the operation is not performed and behaves like a no-op. No error
is returned in this case.

## Returning the modified documents

You can optionally return the documents modified by the query. In this case, the `UPDATE`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -996,6 +996,18 @@ used to specify the following options:
existing document's value. If set to `true`, objects will be merged.
The default is `true`.
This option controls the update-insert behavior only.
- `versionAttribute`: The optional `versionAttribute` adds external versioning
support and can be used with `overwriteMode: "update"` or `overwriteMode: "replace"`.
If set, the attribute with the name specified by the property is
looked up in the document to be updated or to be replaced.
If no such attribute exists, the operation is performed as usual. If such an
attribute exists, its content is read and compared numerically to the value of
the versioning attribute in the document that updates or replaces it.
If the version number in the new document is higher than in the document that
already exists in the database, then the operation is performed normally.
If the version number in the new document is lower or equal to what exists in
the database, the operation is not performed and behaves like a no-op. No error
is returned in this case.

---

Expand Down Expand Up @@ -1301,6 +1313,17 @@ Replaces an existing document, with additional options passed as an object:
revision of the document is returned in the output under the
attribute `old`.
- `silent`: If this flag is set to `true`, no output is returned.
- `versionAttribute`: The optional `versionAttribute` adds external versioning
support. If set, the attribute with the name specified by the property is
looked up in the document to be replaced.
If no such attribute exists, the operation is performed as usual. If such an
attribute exists, its content is read and compared numerically to the value of
the versioning attribute in the document that replaces it.
If the version number in the new document is higher than in the document that
already exists in the database, then the operation is performed normally.
If the version number in the new document is lower or equal to what exists in
the database, the operation is not performed and behaves like a no-op. No error
is returned in this case.

---

Expand Down Expand Up @@ -1473,6 +1496,17 @@ an object:
set to `false`, the value in the patch document will overwrite the
existing document's value. If set to `true`, objects will be merged.
The default is `true`.
- `versionAttribute`: The optional `versionAttribute` adds external versioning
support. If set, the attribute with the name specified by the property is
looked up in the document to be updated.
If no such attribute exists, the operation is performed as usual. If such an
attribute exists, its content is read and compared numerically to the value of
the versioning attribute in the document that updates it.
If the version number in the new document is higher than in the document that
already exists in the database, then the operation is performed normally.
If the version number in the new document is lower or equal to what exists in
the database, the operation is not performed and behaves like a no-op. No error
is returned in this case.

---

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -387,3 +387,21 @@ not handle larger amounts of data and were thus very limited.

Users of the JavaScript-based traversal API should use
[AQL traversal queries](../../aql/graphs/traversals.md) instead.

### `collection` object

`collection.replace(object, data, options)` and
`collection.update(object, data, options)` now have an optional
`versionAttribute` property that adds external versioning support. It can also
be used for `collection.insert(data, options)` with `overwriteMode: "update"`
or `overwriteMode: "replace"`.

If set, the attribute with the name specified by the property is looked up in
the document to be replaced or updated and its content is read and compared
numerically to the value of the versioning attribute in the document that
updates or replaces it.
If the version number in the new document is higher than in the document that
already exists in the database, then the operation is performed normally.
If the version number in the new document is lower or equal to what exists in
the database, the operation is not performed and behaves like a no-op. No error
is returned in this case.
72 changes: 72 additions & 0 deletions site/content/3.12/release-notes/version-3.12/whats-new-in-3-12.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,78 @@ The `move-filters-into-enumerate` optimizer rule can now also move filters into
performance of queries that do a lot of filtering on longer lists of
non-collection data.

### `versionAttribute` property for `UPDATE` and `REPLACE` operations

`UPDATE` and `REPLACE` operations now support an optional `versionAttribute`
property. If set, the attribute with the name specified by the property is
looked up in the document to be updated or to be replaced.

This simple versioning can help to avoid overwriting existing data with older
versions in case data is transferred from an external system into ArangoDB
and the copies are currently not in sync.

The `versionAttribute` property can be used for `INSERT` operations with
`overwriteMode: "update"` or `overwriteMode: "replace"`.
It can also be used inside AQL queries by specifying it in the `OPTIONS`
clause of an `UPDATE`, `REPLACE`, and `INSERT` operation.

If no such attribute exists, the operation is performed as usual. If such an
attribute exists, its content is read and compared numerically to the value of
the versioning attribute in the document that updates or replaces it.
If the version number in the new document is higher than in the document that
already exists in the database, then the operation is performed normally.
If the version number in the new document is lower or equal to what exists in
the database, the operation is not performed and behaves like a no-op. No error
is returned in this case.

**Examples:**

Inserts the new document normally:
```js
db.collection.insert({_key: "hello", value: 1, ver: 1});
```

Updates the document because the value of the `versionAttribute` is higher in the
new document:
```js
db.collection.update("hello",
{value: 2, ver: 2},
{versionAttribute: "ver"});
```

Does not update the document because the value of the `versionAttribute` is lower
in the new document:
```js
db.collection.update("hello",
{value: 3, ver: 1},
{versionAttribute: "ver"});
```

Updates the document because the key already exists and the value of the
`versionAttribute` is higher in the new document:
```js
db.collection.insert({_key: "hello", value: 4, ver: 3},
{overwriteMode: "update", versionAttribute: "ver"});
```

```js
db._query("UPDATE 'hello' WITH {value: 5, ver: 4} IN collection
OPTIONS {versionAttribute: 'ver'}");
```

Versioning is opt-in and no version checking is performed for
operations for which the `versionAttribute` property was not set as part of
the `UPDATE` and `REPLACE` operations or as an option in the AQL query. Document
removal operations do not support versioning. Removal operations are always
carried out normally without checking the version attribute, even if it is specified.

Note that version checking is performed only if both the existing version of
the document in the database and the new document version contain the version
attribute with numeric values between `0` and `18446744073709551615`.
If neither the existing document in the database nor the new document version
does not contain the version attribute, or if the version attribute in any of
the two is not a number inside the valid range, the `UPDATE` and `REPLACE` operations behave as if no version checking was requested.

## Indexing

### Stored values can contain the `_id` attribute
Expand Down