更新(切换)逻辑可以实现如下 - 我将用一个例子来解释。考虑一个包含两个文档的集合:
{ "_id" : 1, "readAt" : "2020-07-01", "fld" : "Y" }
{ "_id" : 2, "fld" : "N" }
以下聚合删除了带有_id: 1 的文档中的readAt字段,并为带有_id: 2 的文档设置了readAt: "2020-07-08"。
var NEW_VALUE = "2020-07-08";
db.collection.aggregate([
{
$addFields: {
readAt: {
$let: {
vars: { readAtExists: { $ifNull: [ "$readAt", null ] } },
in: { $cond: [ {$eq: [ "$$readAtExists", null ]}, NEW_VALUE, "$$REMOVE" ] }
}
}
}
}
])
基于此聚合,您可以通过以下两种方式之一更新文档。 第一个选项适用于 MongoDB 4.2 或更高版本(使用Update with Aggregation Pipeline),第二个选项适用于 4.2 之前的版本。
1) 使用聚合管道更新
db.collection.update(
{ _id: 1 }, // { _id: 2 }
[
{
$set: {
readAt: {
$let: {
vars: { readAtExists: { $ifNull: [ "$readAt", null ] } },
in: { $cond: [ {$eq: [ "$$readAtExists", null ]}, NEW_VALUE, "$$REMOVE" ] }
}
}
}
}
]
)
2) 聚合和更新:
db.collection.aggregate( [
{
$match: { _id: 1 } // { _id: 2 }
},
{
$addFields: {
readAt: {
$let: {
vars: { readAtExists: { $ifNull: [ "$readAt", null ] } },
in: { $cond: [ {$eq: [ "$$readAtExists", null ]}, NEW_VALUE, "$$REMOVE" ] }
}
}
}
}
] ).forEach( doc => db.collection.replaceOne( { _id: doc._id }, doc ) )
注意事项:
您可以在 MongoDB v4.2 中使用 NOW 聚合变量来设置聚合中的日期值。