Skip to content

Commit bd50991

Browse files
authored
Merge pull request #189297 from sajeetharan/patch_updates_limit
Updates for Partial doc update feature
2 parents d4623ba + 4db6d77 commit bd50991

File tree

3 files changed

+78
-55
lines changed

3 files changed

+78
-55
lines changed

articles/cosmos-db/partial-document-update-faq.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ sections:
3535
- question: |
3636
Is there a limit to the number of partial document update operations?
3737
answer: |
38-
There is a limit of 10 patch operations that can be added in a single patch specification. If you need this number to be increased, please contact the [support team](https://portal.azure.com/?#blade/Microsoft_Azure_Support/HelpAndSupportBlade).
39-
38+
There is a limit of 10 patch operations that can be added in a single patch specification.
4039
- question: |
4140
Is partial document update supported for system-generated properties?
4241
answer: |

articles/cosmos-db/partial-document-update-getting-started.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,9 @@ if (response.isSuccessStatusCode()) {
163163
Support for Partial document update (Patch API) in the [Azure Cosmos DB JavaScript SDK](sql/sql-api-sdk-node.md) is available from version *3.15.0* onwards. You can download it from the [NPM Registry](https://www.npmjs.com/package/@azure/cosmos/v/3.15.0)
164164

165165
> [!NOTE]
166-
> A complete partial document update sample can be found in the [.js v3 samples repository](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/cosmosdb/cosmos/samples/v3/typescript/src/ItemManagement.ts#L167) on GitHub.
166+
> A complete partial document update sample can be found in the [.js v3 samples repository](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/cosmosdb/cosmos/samples/v3/typescript/src/ItemManagement.ts#L167) on GitHub. In the sample, as the container is created without a partition key specified, the Javascript SDK
167+
resolves the partition key values from the items through the container's partition
168+
key definition.
167169

168170
**Executing a single patch operation**
169171

articles/cosmos-db/partial-document-update.md

Lines changed: 74 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -11,49 +11,76 @@ ms.custom: ignite-fall-2021
1111
---
1212

1313
# Partial document update in Azure Cosmos DB
14+
1415
[!INCLUDE[appliesto-sql-api](includes/appliesto-sql-api.md)]
1516

16-
Azure Cosmos DB Partial Document Update feature (also known as Patch API) provides a convenient way to modify a document in a container. Currently, to update a document the client needs to read it, execute Optimistic Concurrency Control checks (if necessary), update the document locally and then send it over the wire as a whole document Replace API call.
17+
Azure Cosmos DB Partial Document Update feature (also known as Patch API) provides a convenient way to modify a document in a container. Currently, to update a document the client needs to read it, execute Optimistic Concurrency Control checks (if necessary), update the document locally and then send it over the wire as a whole document Replace API call.
1718

1819
Partial document update feature improves this experience significantly. The client can only send the modified properties/fields in a document without doing a full document replace operation. Key benefits of this feature include:
1920

20-
- **Improved developer productivity**: Provides a convenient API for ease of use and the ability to conditionally update the document.
21+
- **Improved developer productivity**: Provides a convenient API for ease of use and the ability to conditionally update the document.
2122
- **Performance improvements**: Avoids extra CPU cycles on the client side, reduces end-to-end latency and network bandwidth.
2223
- **Multi-region writes**: Supports automatic and transparent conflict resolution with partial updates on discrete paths within the same document.
23-
24+
25+
> [!NOTE]
26+
> *Partial document update* operation is based on the [RFC spec](https://www.rfc-editor.org/rfc/rfc6902#appendix-A.14). To escape a ~ character you need to add 0 or a 1 to the end.
27+
28+
An example target JSON document:
29+
30+
```json
31+
{
32+
"/": 9,
33+
"~1": 10
34+
}
35+
```
36+
37+
A JSON Patch document:
38+
39+
```json
40+
[{ "op": "test", "path": "/~01", "value": 10 }]
41+
```
42+
43+
The resulting JSON document:
44+
45+
```json
46+
{
47+
"/": 9,
48+
"~1": 10
49+
}
50+
```
51+
2452
## Supported operations
2553

2654
The table below summarizes the operations supported by this feature.
2755

28-
> [!NOTE]
29-
> *target path* refers to a location within the JSON document
56+
> [!NOTE]
57+
> _target path_ refers to a location within the JSON document
3058
31-
| **Operation type** | **Description** |
32-
| ------------ | -------- |
33-
| **Add** | `Add` performs one of the following, depending on the target path: <br/><ul><li>If the target path specifies an element that does not exist, it is added.</li><li>If the target path specifies an element that already exists, its value is replaced.</li><li>If the target path is a valid array index, a new element will be inserted into the array at the specified index. It shifts existing elements to the right.</li><li>If the index specified is equal to the length of the array, it will append an element to the array. Instead of specifying an index, you can also use the `-` character. It will also result in the element being appended to the array.</li></ul> <br/> **Note**: Specifying an index greater than the array length will result in an error.|
34-
| **Set** | `Set` operation is similar to `Add` except in the case of Array data type - if the target path is a valid array index, the existing element at that index is updated.|
35-
| **Replace** | `Replace` operation is similar to `Set` except it follows _strict_ replace only semantics. In case the target path specifies an element or an array that does not exist, it results in an error. |
36-
| **Remove** | `Remove` performs one of the following, depending on the target path: <br/><ul><li>If the target path specifies an element that does not exist, it results in an error. </li><li> If the target path specifies an element that already exists, it is removed. </li><li> If the target path is an array index, it will be deleted and any elements above the specified index are shifted one position to the left.</li></ul> <br/> **Note**: Specifying an index equal to or greater than the array length would result in an error. |
37-
| **Increment** | This operator increments a field by the specified value. It can accept both positive and negative values. If the field does not exist, it creates the field and sets it to the specified value. |
59+
| **Operation type** | **Description** |
60+
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
61+
| **Add** | `Add` performs one of the following, depending on the target path: <br/><ul><li>If the target path specifies an element that does not exist, it is added.</li><li>If the target path specifies an element that already exists, its value is replaced.</li><li>If the target path is a valid array index, a new element will be inserted into the array at the specified index. It shifts existing elements to the right.</li><li>If the index specified is equal to the length of the array, it will append an element to the array. Instead of specifying an index, you can also use the `-` character. It will also result in the element being appended to the array.</li></ul> <br/> **Note**: Specifying an index greater than the array length will result in an error. |
62+
| **Set** | `Set` operation is similar to `Add` except in the case of Array data type - if the target path is a valid array index, the existing element at that index is updated. |
63+
| **Replace** | `Replace` operation is similar to `Set` except it follows _strict_ replace only semantics. In case the target path specifies an element or an array that does not exist, it results in an error. |
64+
| **Remove** | `Remove` performs one of the following, depending on the target path: <br/><ul><li>If the target path specifies an element that does not exist, it results in an error. </li><li> If the target path specifies an element that already exists, it is removed. </li><li> If the target path is an array index, it will be deleted and any elements above the specified index are shifted one position to the left.</li></ul> <br/> **Note**: Specifying an index equal to or greater than the array length would result in an error. |
65+
| **Increment** | This operator increments a field by the specified value. It can accept both positive and negative values. If the field does not exist, it creates the field and sets it to the specified value. |
3866

3967
## Supported modes
4068

4169
Partial document update feature supports the following modes of operation. Refer to the [Getting Started](partial-document-update-getting-started.md) document for code examples.
4270

43-
* **Single document patch**: You can patch a single document based on its ID and the partition key. It is possible to execute multiple patch operations on a single document. The [maximum limit is 10 operations](partial-document-update-faq.yml#is-there-a-limit-to-the-number-of-partial-document-update-operations-).
44-
45-
* **Multi-document patch**: Multiple documents within the same partition key can be patched as a [part of a transaction](transactional-batch.md). This transaction will be committed only if all the operations succeed in the order they are described. If any operation fails, the entire transaction is rolled back.
71+
- **Single document patch**: You can patch a single document based on its ID and the partition key. It is possible to execute multiple patch operations on a single document. The maximum limit is 10 operations.
4672

47-
* **Conditional Update** For the aforementioned modes, it is also possible to add a SQL-like filter predicate (for example, *from c where c.taskNum = 3*) such that the operation fails if the pre-condition specified in the predicate is not satisfied.
73+
- **Multi-document patch**: Multiple documents within the same partition key can be patched as a [part of a transaction](transactional-batch.md). This transaction will be committed only if all the operations succeed in the order they are described. If any operation fails, the entire transaction is rolled back.
4874

49-
* You can also use the bulk APIs of supported SDKs to execute one or more patch operations on multiple documents.
75+
- **Conditional Update** For the aforementioned modes, it is also possible to add a SQL-like filter predicate (for example, _from c where c.taskNum = 3_) such that the operation fails if the pre-condition specified in the predicate is not satisfied.
5076

77+
- You can also use the bulk APIs of supported SDKs to execute one or more patch operations on multiple documents.
5178

5279
## Similarities and differences
5380

5481
### Add vs Set
5582

56-
`Set` operation is similar to `Add` for all data types except `Array`. An `Add` operation at any (valid) index, results in the addition of an element at the specified index and any existing elements in array end up shifting to the right. This is in contrast to `Set` operation that updates the existing element at the specified index.
83+
`Set` operation is similar to `Add` for all data types except `Array`. An `Add` operation at any (valid) index, results in the addition of an element at the specified index and any existing elements in array end up shifting to the right. This is in contrast to `Set` operation that updates the existing element at the specified index.
5784

5885
### Add vs Replace
5986

@@ -63,7 +90,7 @@ Partial document update feature supports the following modes of operation. Refer
6390

6491
`Set` operation adds a property if it doesn't already exist (except if there was an `Array`). `Replace` operation will fail if the property does not exist (applies to `Array` data type as well).
6592

66-
> [!NOTE]
93+
> [!NOTE]
6794
> `Replace` is a good candidate where the user expects some of the properties to be always present and allows you to assert/enforce that.
6895
6996
## REST API reference for Partial document update
@@ -73,24 +100,24 @@ The [Azure Cosmos DB REST API](/rest/api/cosmos-db/) provides programmatic acces
73100
For example, here is what the request looks like for a `set` operation using Partial document update.
74101

75102
```json
76-
PATCH https://querydemo.documents.azure.com/dbs/FamilyDatabase/colls/FamilyContainer/docs/Andersen.1 HTTP/1.1
77-
x-ms-documentdb-partitionkey: ["Andersen"]
78-
x-ms-date: Tue, 29 Mar 2016 02:28:29 GMT
103+
PATCH https://querydemo.documents.azure.com/dbs/FamilyDatabase/colls/FamilyContainer/docs/Andersen.1 HTTP/1.1
104+
x-ms-documentdb-partitionkey: ["Andersen"]
105+
x-ms-date: Tue, 29 Mar 2016 02:28:29 GMT
79106
Authorization: type%3dmaster%26ver%3d1.0%26sig%3d92WMAkQv0Zu35zpKZD%2bcGSH%2b2SXd8HGxHIvJgxhO6%2fs%3d
80107
Content-Type:application/json_patch+json
81-
Cache-Control: no-cache
82-
User-Agent: Microsoft.Azure.DocumentDB/2.16.12
83-
x-ms-version: 2015-12-16
84-
Accept: application/json
85-
Host: querydemo.documents.azure.com
86-
Cookie: x-ms-session-token#0=602; x-ms-session-token=602
87-
Content-Length: calculated when request is sent
108+
Cache-Control: no-cache
109+
User-Agent: Microsoft.Azure.DocumentDB/2.16.12
110+
x-ms-version: 2015-12-16
111+
Accept: application/json
112+
Host: querydemo.documents.azure.com
113+
Cookie: x-ms-session-token#0=602; x-ms-session-token=602
114+
Content-Length: calculated when request is sent
88115
Connection: keep-alive
89-
116+
90117
{"operations":[{ "op" :"set", "path":"/Parents/0/FamilyName","value":"Bob" }]}
91118
```
92119

93-
## Document level vs path level conflict resolution
120+
## Document level vs path level conflict resolution
94121

95122
If your Azure Cosmos DB account is configured with multiple write regions, [conflicts and conflict resolution policies](conflict-resolution-policies.md) are applicable at the document level, with Last Write Wins (`LWW`) being the default conflict resolution policy. For partial document updates, patch operations across multiple regions detect and resolve conflicts at a more granular path level.
96123

@@ -99,39 +126,34 @@ This can be better understood with an example.
99126
Assume that you have following document in Azure Cosmos DB:
100127

101128
```json
102-
{
103-
   "id":1,
104-
   "name":"John Doe",
105-
   "email":"[email protected]",
106-
   "phone":[ 
107-
      "12345",
108-
"67890"
109-
   ],
110-
   "level":"gold"
111-
}
129+
{
130+
"id": 1,
131+
"name": "John Doe",
132+
"email": "[email protected]",
133+
"phone": ["12345", "67890"],
134+
"level": "gold"
135+
}
112136
```
113137

114138
The below Patch operations are issued concurrently by different clients in different regions:
115139

116-
- `Set` attribute `/level` to platinum
140+
- `Set` attribute `/level` to platinum
117141
- `Remove` 67890 from `/phone`
118142

119143
:::image type="content" source="./media/partial-document-update/patch-multi-region-conflict-resolution.png" alt-text="An image that shows conflict resolution in concurrent multi-region partial update operations." border="false" lightbox="./media/partial-document-update/patch-multi-region-conflict-resolution.png":::
120144

121-
Since Patch requests were made to non-conflicting paths within the document, these will be conflict resolved automatically and transparently (as opposed to Last Writer Wins at a document level).
145+
Since Patch requests were made to non-conflicting paths within the document, these will be conflict resolved automatically and transparently (as opposed to Last Writer Wins at a document level).
122146

123147
The client will see the following document after conflict resolution:
124148

125149
```json
126-
{
127-
   "id":1,
128-
   "name":"John Doe",
129-
   "email":"[email protected]",
130-
   "phone":[ 
131-
      "12345"
132-
   ],
133-
   "level":"platinum",
134-
}
150+
{
151+
"id": 1,
152+
"name": "John Doe",
153+
"email": "[email protected]",
154+
"phone": ["12345"],
155+
"level": "platinum"
156+
}
135157
```
136158

137159
> [!NOTE]

0 commit comments

Comments
 (0)