当我已经知道文档id时,我试图在嵌套数组中删除匹配条件的特定元素。
{
"id": "Tim",
"city": "Seattle",
"gifts": [
{
"recipient": "Andrew",
"gift": "blanket"
},
{
"recipient": "Deborah",
"gift": "board game"
},
{
"recipient": "Chris",
"gift": "coffee maker"
}
]
}
我想从"gifts"数组中删除收件人为"Andrew"的所有元素。一个幼稚的方法是拉文档,删除数组元素,然后设置新文档。但这让我很担心,因为它暴露了一个竞争条件,在拉文档和更新文档的过程中,可能会对该数组进行不同的变异,而这些变异将丢失。
我想看看我是否可以执行部分文档更新来删除数组元素。但是,https://learn.microsoft.com/en-us/azure/cosmos-db/partial-document-update的部分文档更新文档声明(表示"删除"):
如果目标路径是数组索引,则将删除该索引,并将指定索引上方的所有元素向左移动一个位置。
因此,通过部分文档更新删除数组元素的唯一方法似乎是通过其数组索引。但是,如果我拉取其数组索引,然后执行更新,则会出现类似的争用情况:如果数组在提取文档和执行部分文档更新之间发生了变化,会怎么样?
我看到对于部分文档更新,您可以执行"条件更新":
有条件更新:对于上述模式,还可以添加类似SQL的过滤器 predicate (例如,从c开始,其中c. taskNum = 3),以便在 predicate 中指定的前提条件不满足时操作失败。
我想知道这是否是我可以用来实现我的目标的东西。
本质上,我想我在寻找类似https://www.mongodb.com/docs/manual/reference/operator/update/pull/的东西,但在SQL API中。
1条答案
按热度按时间5q4ezhmt1#
数组在提取文档和执行部分文档更新之间发生变化
避免对同一文档进行并发更新的唯一方法是执行乐观并发。您需要首先读取当前文档,获取它的
ETag
,然后将其传递给CosmosItemRequestOptions
函数以用于更新操作:完整示例:https://github.com/Azure-Samples/azure-cosmos-java-sql-api-samples/blob/0ead4ca33dac72c223285e1db866c9dc06f5fb47/src/main/java/com/azure/cosmos/examples/documentcrud/async/DocumentCRUDQuickstartAsync.java#L366-L418
在这种情况下,如果发生了任何并发更新,您将得到一个带有状态代码412的失败,这意味着发生了并发更新,您需要重试操作(读取、获取新etag、找到要删除的新索引、执行更新)。