MongoDB Update Aggregation Pipeline 能否有条件地替换文档?
Can MongoDB Update Aggregation Pipeline conditionally replace the document?
给定一个文档;
{
"name": "Jason",
"foo": "bar",
"version": 3,
// ...
}
是否可以指定更新聚合管道以根据当前文档的 属性 有条件地更新整个文档?即指定类似;
const newDocument = { ...currentDocument, version: 4, foo: "baz" };
if (document.version == 3)
$replaceRoot(newDocument)
else
doNothing()
Post 回答编辑
下面标记的答案确实解决了这个问题。为了完整起见,我想添加一些背景来说明为什么会问这个问题,因为答案会略有变化。
CosmosDB 提供 Optimistic Concurrency Control (OCC) 的功能,允许 CosmosDB 在文档发生意外更改时拒绝文档上的命令。需要注意的重要一点是,客户端可以提供文档的预期版本 (_etag
属性)。
MongoDB 确实在后台使用了此功能,但不会向客户端公开 OCC。这意味着您的整个文档更改需要在 Mongo 更新管道语法中进行描述。这种语法适用于简单的文档和更新命令。但是,它不能替代可测试的业务逻辑代码。
要在使用 MongoDB 时向客户端公开 OCC,请使用 version
属性 或类似的并确保在命令过滤器中以预期版本为目标,如所述 .
是的,可以,您可以像以前一样在代码中构建更新管道,但您也可以在 Mongo 中使用 $cond
这样做:
db.collection.updateOne({},
[
{
$replaceRoot: {
newRoot: {
$cond: [
{
$eq: [
"$version",
3
]
},
{
$mergeObjects: [
"$$ROOT",
{
version: 4,
foo: "baz"
}
]
},
"$$ROOT"
]
}
}
}
])
给定一个文档;
{
"name": "Jason",
"foo": "bar",
"version": 3,
// ...
}
是否可以指定更新聚合管道以根据当前文档的 属性 有条件地更新整个文档?即指定类似;
const newDocument = { ...currentDocument, version: 4, foo: "baz" };
if (document.version == 3)
$replaceRoot(newDocument)
else
doNothing()
Post 回答编辑
下面标记的答案确实解决了这个问题。为了完整起见,我想添加一些背景来说明为什么会问这个问题,因为答案会略有变化。
CosmosDB 提供 Optimistic Concurrency Control (OCC) 的功能,允许 CosmosDB 在文档发生意外更改时拒绝文档上的命令。需要注意的重要一点是,客户端可以提供文档的预期版本 (_etag
属性)。
MongoDB 确实在后台使用了此功能,但不会向客户端公开 OCC。这意味着您的整个文档更改需要在 Mongo 更新管道语法中进行描述。这种语法适用于简单的文档和更新命令。但是,它不能替代可测试的业务逻辑代码。
要在使用 MongoDB 时向客户端公开 OCC,请使用 version
属性 或类似的并确保在命令过滤器中以预期版本为目标,如所述
是的,可以,您可以像以前一样在代码中构建更新管道,但您也可以在 Mongo 中使用 $cond
这样做:
db.collection.updateOne({},
[
{
$replaceRoot: {
newRoot: {
$cond: [
{
$eq: [
"$version",
3
]
},
{
$mergeObjects: [
"$$ROOT",
{
version: 4,
foo: "baz"
}
]
},
"$$ROOT"
]
}
}
}
])