如何对MongoDB嵌套文档中指定条件的temp字段四舍五入?
解决MongoDB嵌套数组字段四舍五入更新的错误问题
错误原因
你之前的两条更新命令报错,核心原因是:普通更新模式下的$set不支持直接使用聚合运算符作为字段值。MongoDB会把你写的$round当成一个要存储的字段名,而美元符号$开头的字段名不允许被存入集合,因此触发了The dollar ($) prefixed field '$round' in 'readings.0.temp.$round' is not valid for storage的错误。
正确解决方案
要实现基于现有字段值计算并更新的需求,必须使用聚合管道形式的updateMany,通过聚合运算符处理数组元素:
db.temperatures.updateMany( { "readings.period": "morning" }, // 匹配包含morning时段读数的文档 [ { $set: { "readings": { $map: { input: "$readings", as: "item", in: { $cond: [ { $eq: ["$$item.period", "morning"] }, // 判断当前读数是否为morning时段 { // 是则生成新的读数对象,temp四舍五入保留两位小数 period: "$$item.period", temp: { $round: ["$$item.temp", 2] } }, "$$item" // 非morning时段直接保留原读数 ] } } } } } ] )
命令说明
- 用聚合数组替代普通更新的
$set语句,允许使用聚合运算符处理字段值 $map遍历readings数组的每个元素:- 借助
$cond判断当前元素的时段是否为morning - 符合条件的元素重新构造,用
$round将temp四舍五入到两位小数 - 不符合条件的元素直接保留原有内容
- 借助
- 最终用
$set替换整个readings数组为处理后的结果
验证效果
执行命令后查询集合,会看到:
- New York的morning时段
temp变为32.23 - Rio的morning时段
temp保持32(整数四舍五入后无变化) - Sampa的morning时段
temp变为32.12
内容的提问来源于stack exchange,提问作者Rodrigo
相关产品推荐
相关产品推荐

