适用范围: NoSQL
Azure Cosmos DB 部分文档更新功能(也称为补丁 API)提供了一种在容器中修改文档的便捷方法。 目前,若要更新某个文档,客户端需要读取该文档,执行乐观并发控制检查(如有必要),在本地更新文档,然后将其作为整个文档通过网络发送以替换 API 调用。
部分文档更新功能显着改善了这种体验。 客户端仅发送文档中修改过的属性/字段,而不进行完整的文档替换操作。 此功能的主要优点包括:
- 提高开发人员的工作效率:提供方便的 API,以便于使用并能够有条件地更新文档。
- 性能改进:在客户端上避免额外的 CPU 周期,减少端到端延迟和网络带宽。
- 多区域写入:通过对同一文档中的离散路径进行部分更新,支持自动和透明的冲突解决方案。
备注
部分文档更新 操作基于 RFC 规范。若要对 ~ 字符进行转义,需要将 0 或 1 添加到末尾。
目标 JSON 文档示例:
{
"id": "e379aea5-63f5-4623-9a9b-4cd9b33b91d5",
"name": "R-410 Road Bicycle",
"price": 455.95,
"inventory": {
"quantity": 15
},
"used": false,
"categoryId": "road-bikes",
"tags": ["r-series"]
}
JSON 修补文档:
[
{ "op": "add", "path": "/color", "value": "silver" },
{ "op": "remove", "path": "/used" },
{ "op": "set", "path": "/price", "value": 355.45 }
{ "op": "incr", "path": "/inventory/quantity", "value": 10 },
{ "op": "add", "path": "/tags/-", "value": "featured-bikes" }
]
生成的 JSON 文档:
{
"id": "e379aea5-63f5-4623-9a9b-4cd9b33b91d5",
"name": "R-410 Road Bicycle",
"price": 355.45,
"inventory": {
"quantity": 25,
"color": "silver"
},
"categoryId": "road-bikes",
"tags": ["r-series", "featured-bikes"]
}
此表总结了此功能支持的操作。
备注
目标路径是指 JSON 文档中的某个位置
操作类型 | 说明 |
---|---|
添加 | Add 执行以下操作之一,具体取决于目标路径:• 如果目标路径指定了一个不存在的元素,则添加该元素。 • 如果目标路径指定了一个已存在的元素,则替换其值。 • 如果目标路径是有效的数组索引,则将新元素插入到指定索引处的数组中。 这会将现有元素移到新元素之后。 • 如果指定的索引等于数组的长度,它会向数组追加一个元素。 除了指定索引,也可以使用 - 字符。 它还会导致向数组追加元素。注意:指定的索引大于数组长度时会导致错误。 |
设置 | Set 操作与 Add 类似,但 Array 数据类型除外。 如果目标路径是有效的数组索引,则更新该索引处的现有元素。 |
将 | Replace 操作与 Set 类似,但它遵循严格的仅替换语义。 如果目标路径指定了不存在的元素或数组,则会导致错误。 |
删除 | Remove 执行以下操作之一,具体取决于目标路径:• 如果目标路径指定了一个不存在的元素,则会导致错误。 • 如果目标路径指定了一个已存在的元素,则将其删除。 • 如果目标路径是一个数组索引,则将其删除并将指定索引上方的任何元素都回移一个位置。 注意:如果指定的索引等于或大于数组长度,将导致错误。 |
增量 | 此运算符按指定的值增加字段。 它可以接受正值和负值。 如果字段不存在,它会创建字段并将其设置为指定值。 |
移动 | 此运算符删除指定位置的值,并将其添加到目标位置。 操作对象必须包含一个“from”成员,该成员是包含 JSON 指针值的字符串,其中的指针值引用目标文档中要从中移动值的位置。 必须存在“from”位置,操作才能成功。如果“path”位置建议的对象不存在,则会创建对象并将值设置为等于“from”位置的值 •如果“path”位置建议的对象已存在,则会将“path”位置的值替换为“from”位置的值 •“Path”属性不能是“from”JSON 位置的 JSON 子级 |
部分文档更新功能支持以下运算模式。 有关代码示例,请参阅入门文档。
单个文档补丁:可以根据文档 ID 和分区键对单个文档进行修补。 可以对单个文档执行多个修补操作。 最大限制为 10 次操作。
多文档补丁:同一分区键内的多个文档可以作为事务的一部分进行修补。 仅当所有操作均按所述顺序成功完成时,此多文档事务才会提交。 如果任何操作失败,将回滚整个事务。
条件更新:对于上述模式,也可以添加一个类似 SQL 的筛选器谓词(例如
from c where c.taskNum = 3
),如果不满足谓词中指定的前提条件,那么操作将失败。也可使用支持的 SDK 的批量 API 对多个文档执行一个或多个修补操作。
我们来比较一下支持的模式之间的相似之处和差别。
对于除 Array
之外的所有数据类型,Set
操作类似于 Add
。 在任何(有效)索引处执行 Add
操作后,都会在指定索引处添加一个元素,并且数组中的任何现有元素最终都会移到该元素之后。 此行为与更新指定索引处的现有元素的 Set
操作相反。
Add
操作添加一个不存在的属性(包括 Array
数据类型)。 如果属性不存在,则 Replace
操作失败(也适用于 Array
数据类型)。
Set
操作添加一个不存在的属性(除非存在 Array
)。 如果属性不存在,则 Replace
操作失败(也适用于 Array
数据类型)。
备注
如果用户希望某些属性始终存在并且允许断言/强制执行该属性,则 Replace
是一个不错的选项。
Azure Cosmos DB REST API 提供对 Azure Cosmos DB 资源的编程访问权限,以创建、查询和删除数据库、文档集合和文档。 除了对集合中的 JSON 文档执行插入、替换、删除、读取、枚举和查询操作外,还可以对部分文档更新操作使用 PATCH
HTTP 方法。 请参阅 Azure Cosmos REST API 参考了解详细信息。
例如,以下描述了对使用部分文档更新的 set
操作的请求。
PATCH https://querydemo.documents.azure.cn/dbs/FamilyDatabase/colls/FamilyContainer/docs/Andersen.1 HTTP/1.1
x-ms-documentdb-partitionkey: ["Andersen"]
x-ms-date: Tue, 29 Mar 2016 02:28:29 GMT
Authorization: type%3dmaster%26ver%3d1.0%26sig%3d92WMAkQv0Zu35zpKZD%2bcGSH%2b2SXd8HGxHIvJgxhO6%2fs%3d
Content-Type:application/json_patch+json
Cache-Control: no-cache
User-Agent: Microsoft.Azure.DocumentDB/2.16.12
x-ms-version: 2015-12-16
Accept: application/json
Host: querydemo.documents.azure.cn
Cookie: x-ms-session-token#0=602; x-ms-session-token=602
Content-Length: calculated when request is sent
Connection: keep-alive
{
"operations": [
{
"op": "set",
"path": "/Parents/0/FamilyName",
"value": "Bob"
}
]
}
如果 Azure Cosmos DB 帐户配置了多个写入区域,则冲突和冲突解决策略适用于文档级别,其中最后写入者胜出 (LWW
) 是默认的冲突解决策略。 对于部分文档更新,跨多个区域的修补操作会检测和解决更详细的路径级别上的冲突。
通过示例可以更好地理解冲突解决。
假设 Azure Cosmos DB 中有以下文档:
{
"id": 1,
"name": "John Doe",
"email": "jdoe@contoso.com",
"phone": ["12345", "67890"],
"level": "gold"
}
不同客户端跨不同区域并发发出修补操作:
Set
属性/level
为白金- 从
/phone
中Remove
67890
由于修补请求是针对文档中的非冲突路径发出的,因此这些请求会以透明方式自动解决冲突(与文档级别的“以最后写入者为准”相反)。
解决冲突后,客户端将看到以下文档:
{
"id": 1,
"name": "John Doe",
"email": "jdoe@contoso.com",
"phone": ["12345"],
"level": "platinum"
}
备注
如果在多个区域中同时修补文档的同一属性,则应用常规的冲突解决策略。
Azure Cosmos DB 中的更改源侦听容器中发生的任何更改,然后输出已更改的文档。 使用更改源,可看到文档的所有更新,包括部分和完整文档更新。 处理来自更改源中的项时,即使更新是修补操作的结果,也会返回完整的文档。
有关 Azure Cosmos DB 中的更改源的详细信息,请参阅 Azure Cosmos DB 中的更改源。