Now Generally Available – Partial Document Update in Azure Cosmos DB
By Saranya Sriram, Abhishek Gupta
We’re excited to announce the general availability of partial document update for the Azure Cosmos DB Core (SQL) API, which was announced at Microsoft Ignite! This new feature makes it possible to perform path-level updates to specific fields/properties in a single document without needing to perform a full document read-replace operation. Partial document update is currently supported in Azure Cosmos DB .NET SDK, Java SDK, Node SDK, and stored procedures.
Document updates – then and now
To put things in context, here is a refresher on how one would typically use a document replace operation: Read the document, update it locally (client side) including any optimistic concurrency control (OCC) checks if necessary and, finally call the replace operation along with the updated document.
Here is a trimmed down example of how one would use partial document update (using the Java SDK):
//step 1 UserInfo user = container.readItem(user.getId(), new PartitionKey(user.getEmail()), UserInfo.class); //step 2 CosmosPatchOperations patchOps = CosmosPatchOperations.create().add("/phone/2",12345).set("/address","123 Foobar"); //step 3 container.patchItem(user.getId(), new PartitionKey(user.getEmail()), patchOps, reqOps, UserInfo.class);
- Read the document (this is the same as replace) with readItem method.
- Define the updates you want to make (in form of a CosmosPatchOperations object – in this case we add a phone number (an array) and set the address to a different one.
- Invoke the patchItem method.
Benefits of partial document update
When compared with the replace operation, the overhead of serializing the entire document is eliminated since the client application only needs to deal with properties to be updated (phone and address in this example). This becomes significant when your application makes frequent updates to only a few properties in your documents, such as incrementing counters, toggling true/false flags or similar types of changes.
Not having to send the entire document over the wire impacts overall application performance – reduced network bandwidth usage, lower end-to end-latency and savings of CPU cycles on the Azure Cosmos DB SDK client hosts.
Some of the other developer productivity benefits that are a by-product of the flexible programming model enabled by partial document update:
- Combining multiple operations: Partial document update supports different types of operations (see next section). Depending on your requirements, you can combine multiple such operations as part of a single invocation as opposed to incurring cost of round trips for separate operation type.
- Conditional update: If you want the partial update to depend on a pre-condition, you can define it using a SQL-like filter predicate (for example, from c where c.taskNum = 3). The partial update operation will fail if the pre-condition specified in the predicate is not satisfied.
- Transactions support: Partial document update works in the context of a Transactional batch as well. This means that multiple documents within the same partition key can be patched (partially updated) as part of a transaction (along with other operations such as create). The transaction will be committed only if all the operations succeed. If any operation fails, the entire transaction is rolled back.
- Transparent conflict resolution: If your Azure Cosmos DB account is configured with multiple write regions, conflicts and respective resolution policies are applicable at the document level (with Last Write Wins being the default conflict resolution policy). This works differently in case of partial document updates – conflicts that occur due to concurrent patch operations to the same document across multiple regions will be detected and resolved at the path-level. This means that as long as you’re updating different properties (paths) in the same document, they will be merged successfully.
Partial document update operations
Although Partial document update is a top-level operation (just like Replace), it supports sub-operations (the code snippet above used add and set). You can refer to the documentation for details, but here is a summary:
- Add: Creates a new element (if it does not already exist).
- Set: Updates an element (creates one if it does not already exist).
- Replace: Updates an element only if it already exists.
- Remove: Deletes an existing element.
- Increment: Increases/decreases by specified value (use negative value to decrease).
Find out more about Azure Cosmos DB partial document update:
- Read the concepts
- Code samples to get you started
- Add/Set/Replace operations – how are they similar, yet different
- Frequently asked questions
Get started free with Azure Cosmos DB.
I tried to use the new patch operations like “PatchItemAsync” on an existing C# application and existing Cosmos DB subscription with SQL SDK 3.22.1 (via Nuget).
But I get always the compile error “Error CS1061 ‘Container’ does not contain a definition for ‘PatchItemAsync’ and no accessible extension method ‘PatchItemAsync’ accepting a first argument of type ‘Container’ could be found (are you missing a using directive or an assembly reference?)”
Do I use the wrong SDK version? Or what other reason could be?
Can you please check if you’re using the version specified here https://docs.microsoft.com/en-us/azure/cosmos-db/partial-document-update-getting-started ?
Where can I get details on the updates for the stored procedure server side SDK? I don’t see any updates on the existing documentation other than the one single example.
We will be adding details soon. Appreciate your patience! Do you mind providing a bit more detail on what you’re looking for in terms of stored procedures?
Documentation for is updated with more details . Hope this helps
I tried via Java for partial update which did worked for me as expected.
Is there a way we can do this in Scala. I am using the Java SDK in my spark cluster and I wanted to do a patchAdd :-
I have retrieved my record and saved as dataframe in scala-spark. Now I want to add the below in the dataframe to do an patchadd like below:
CosmosPatchOperations patchOps = CosmosPatchOperations.create().add(“/phone/2”,12345).set(“/address”,”123 Foobar”);
container.patchItem(user.getId(), new PartitionKey(user.getEmail()), patchOps, reqOps, UserInfo.class);
how can we do this in SCALA-SHELL? is it possible
I suppose this PatchOperation also helps in getting rid of handling OCC by developers as patching is supposed to be atomic in this case (when clients are updating different paths of same document at same time). Please correct me if I am wrong.
If what you’re describing (“clients are updating different paths of same document at same time”) happens in a multi-region setup, conflict resolution is handled transparently – https://docs.microsoft.com/en-us/azure/cosmos-db/partial-document-update#document-level-vs-path-level-conflict-resolution
In case of same (single) region, existing OCC rules apply https://docs.microsoft.com/en-us/azure/cosmos-db/sql/database-transactions-optimistic-concurrency#optimistic-concurrency-control
Will Spring data cosmos support this?