如何用MongoDB聚合操作更新数组子对象的自身字段值
问题:MongoDB批量更新数组内对象的指定字段值
需要将文档中foos数组内每个子对象的val字段值乘以10,示例如下:
// 原文档 { foos: [ { val: 1 }, { val: 10 }, { val: 5 }, ] } // 更新后 { foos: [ { val: 10 }, { val: 100 }, { val: 50 }, ] }
尝试过的无效方法:
- 此方法会丢失原对象结构,直接将
foos数组替换为纯数值数组:
// 不生效,会将值从父对象中拆分出来 coll.updateMany({}, [ {$set: { foos: {$map: { input: '$foos', as: 'foo', in: {$multiply: ['$$foo.val', 10]} }} }} ])
- 此方法报错,无法直接对数组内所有元素使用位置操作符
$执行聚合更新:
// 报错:MongoServerError: $multiply only supports numeric types, not string coll.updateMany({}, [ { $set: { 'foos.val': {$multiply: ['$foos.$.val', 10]} } } ])
正确的聚合更新实现
可以使用$mergeObjects操作符,将原对象与更新后的val字段合并,既保留原对象的所有字段,又完成val的乘法更新:
coll.updateMany({}, [ { $set: { foos: { $map: { input: '$foos', as: 'foo', in: { $mergeObjects: [ '$$foo', // 保留原对象的所有字段 { val: { $multiply: ['$$foo.val', 10] } } // 更新val字段 ] } } } } } ])
这个方法通过$map遍历foos数组的每个元素,再用$mergeObjects把原对象和新的val字段合并,实现了只更新指定字段且保留原对象结构的需求。
内容的提问来源于stack exchange,提问作者OoDeLally
相关产品推荐
相关产品推荐

