MongoDB使用$set和$sum更新数据报错,求非聚合解决方案
问题解决:MongoDB updateOne累加数组字段值报错的非聚合方案
你的代码报错原因是:普通更新操作中的$set不支持使用$sum这类聚合操作符引用文档内的现有字段,MongoDB会将{ $sum: "$report.views" }当作普通字段值存储,而美元符号前缀的字段名不合法,因此触发错误。
无需使用聚合的解决办法是分两步操作:先查询文档获取当前的views总和,手动计算新的总和后再执行更新,具体实现如下:
代码示例
// 第一步:查询目标文档,计算当前views总和 const targetDoc = await single_sku_db.collection("test").findOne({ _id: ObjectId(id) }); if (!targetDoc) { // 处理文档不存在的情况 return; } // 累加现有report数组中的views值 const currentTotalViews = targetDoc.report.reduce((total, item) => total + item.views, 0); // 加上本次要新增的views值 const newTotalViews = currentTotalViews + views; // 第二步:执行更新操作 await single_sku_db.collection("test").updateOne( { _id: ObjectId(id) }, { $push: { report: { $each: [ { name: name, views, }, ], $position: 0, }, }, $set: { report_status: "Completed", total_views: newTotalViews, }, } );
注意事项
- 这种方式存在竞态风险:如果在查询和更新之间,有其他操作修改了目标文档的
report或total_views,会导致计算结果不准确。 - 如果需要避免竞态,可以添加乐观锁机制(比如给文档增加
version字段,更新时匹配当前版本号),或者在MongoDB 4.2及以上版本使用聚合管道式更新(虽然你要求无需聚合,但可以作为备选方案)。
内容的提问来源于stack exchange,提问作者ELsssss
相关产品推荐
相关产品推荐

