Mongoose如何更新对象数组?匹配indexName为'bcd'时将isFilter设为true
MongoDB数组字段更新不生效问题排查与解决方案
错误原因
你代码的核心问题有3个:
- 占位符未替换:代码中的
<document>是示例占位符,需要替换为你实际操作的集合实例(原生MongoDB为db.你的集合名,Mongoose为对应的模型对象),否则代码会直接抛出语法错误无法运行。 - 冗余配置了
multi: true参数:updateMany()方法本身的作用就是更新所有匹配的文档,multi是旧版update()方法才需要的参数,多余的配置会导致部分MongoDB驱动、低版本实例无法正确解析更新选项,最终更新不生效。 - 未确认MongoDB版本支持:
arrayFilters是MongoDB 3.6版本才推出的功能,如果你运行实例的版本低于3.6,该语法会完全不生效。
额外排查点:
可以先执行查询语句确认集合中确实存在匹配的文档,避免无匹配数据导致看起来更新不生效:
db.你的集合名.find({"attr.indexName": "bcd"})
如果你使用Mongoose ODM,需要确保Mongoose版本在5.0以上,才默认支持arrayFilters语法。
正确可运行代码
原生MongoDB写法
db.你的实际集合名.updateMany( {}, // 如果你只需要更新特定文档,在这里填写文档过滤条件 { $set: { "attr.$[elem].isFilter": true } }, { arrayFilters: [ { "elem.indexName": "bcd" } ] } )
Mongoose写法
// 替换为你实际的Mongoose模型对象 Product.updateMany( {}, { $set: { "attr.$[elem].isFilter": true } }, { arrayFilters: [{ "elem.indexName": "bcd" }] } )
低版本兼容方案
如果你的MongoDB版本低于3.6无法使用arrayFilters,可以用遍历更新的方式实现:
db.你的集合名.find({"attr.indexName": "bcd"}).forEach(doc => { doc.attr.forEach(item => { if(item.indexName === 'bcd') { item.isFilter = true; } }) db.你的集合名.save(doc); })
内容的提问来源于stack exchange,提问作者David Jung Basnet
相关产品推荐
相关产品推荐

