我试图用以下事务执行MongoDB记录的条件更新。
db.collection(SESSIONS_COLLECTION)
.updateOne({_id: ObjectId(id)},
{
$set: {
end: {
$cond: {
if: { $gt: ["$end", latestActionDate] }, then: "$end", else: latestActionDate
}
}
},
$push: {
actions: {
$each: data.map(action => ({
...action,
time: new Date(action.time)
}))
}
}
}
);
但我所有的努力都被粉碎了。 MongoError:'end.$cond'中的dollar($)前缀字段'$cond'对于存储无效。
可能根本不允许这样的操作,但我更愿意认为我遗漏了一些东西。
问题是您将正常的更新操作与聚合运算符混在一起,要在更新中使用聚合运算符,您需要将更新部分包装在[]
中,以说明它实际上是一个聚合管道。
启动MongoDB版本4.2
时,可以使用聚合管道更新:
代码:
let actionArray = data.map((action) => ({
...action,
time: new Date(action.time),
}));
db.collection(SESSIONS_COLLECTION).updateOne({ _id: ObjectId(id) }, [
{
$set: {
end: {
$cond: [{ $gt: ["$end", latestActionDate] }, "$end", latestActionDate]
}
}
},
/** (fail safe stage) this second stage is optional but needed in general as `$push` will add a new array
* if that field doesn't exists earlier to update operation
* but `$concatArray` doesn't, So this helps to add `[]` prior to below step */
{
$set: { actions: { $ifNull: [ "$actions", [] ] } }
},
{
$set: {
actions: { $concatArrays: ["$actions", actionArray] }
}
}
]);
注意:
由于我们在这里使用聚合管道,您需要使用聚合运算符,而使用很少的查询/更新运算符是行不通的。