googleapis / googleapis/google-cloud-node
FR: Extend API for update operations to allow cases where the document may not exist
- Dominant language
- TypeScript
- Stars
- 3.2k
- Forks
- 712
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 99
Description
**Is your feature request related to a problem? Please describe.**
We have a scenario where we want to update multiple documents at once (atomically, using a batch write) without knowing **or caring** if all involved documents currently exist.
For example, say we have the following three documents with their current contents:
```
/abc/123
- fieldA: "foo"
- fieldB: "bar"
- fieldC: "baz"
/abc/456
- fieldA: "foo"
- fieldB: "qux"
- fieldC: "fred"
/abc/789
```
We want to perform an atomic update of all three of these documents, and have Firestore simply skip the documents that don't exist. Essentially, we want Firestore to guarantee that the specified document(s) **that existed** were updated.
**Describe the solution you'd like**
There are a number of ways this could be added to the public API as an opt-in feature without changing current behavior.
One way this could manifest would be to add an optional `options` argument similar to that in the `set` method that could follow the `preconditions` argument; It could look something like this:
```
const batch = firestore.batch()
batch.update(docRef123, {fieldA: "waldo"}, {}, {skipNotFound: true})
batch.update(docRef456, {fieldA: "waldo"}, {}, {skipNotFound: true})
batch.update(docRef789, {fieldA: "waldo"}, {}, {skipNotFound: true})
await batch.commit()
```
Another option could be to change the accepted preconditions for `update` so that developers can use the `exists` field, similar to `delete`. The default would remain `true` but developers could instead explicitly pass another value such as `null` (`false` probably wouldn't be appropriate, but `null` could be read as "_the caller explicitly doesn't care if it exists_").
**Describe alternatives you've considered**
We do not want to use `set` because we don't want the document to be created if it does not already exist. It is possible today to achieve the desired outcome using transactions, however this alternative is much messier, requires additional reads, and is likely heavier in terms of database load and/or contention than the proposed solution. I'm not familiar with the internal API so I can only speak from the perspective of the public API, where it sure would appear to be cleaner and more efficient to use the batch write with the modified update operations instead of using a transaction to lock, fetch, check, and exclude each document that doesn't exist. Maybe someone can inform me if I'm right about that or not.
**Additional context**
None at this time.
Contributor guide
Assessment
This issue has not been assessed yet.