如何一次性更新Mongoose数组中的所有对象?
问题:批量更新Mongoose数组中所有符合条件的元素
需要将Mongoose文档中conversation数组内所有responsed为false的对象的该字段设为true,但自行编写的updateOne代码仅能更新第一个符合条件的对象,其余对象无变化,请求解决。
初始数据
{ "_id": { "$oid": "64e460061cbb782e29b8b067" }, "threadId": { "$oid": "64e460061cbb782e29b8b065" }, "contactId": { "$oid": "64e460051cbb782e29b8b063" }, "status": true, "conversation": [ { "response": "ABC", "status": false, "_id": { "$oid": "64e460051cbb782e29b8b061" }, "responsed": false }, { "response": "DEF", "status": false, "_id": { "$oid": "64e460051cbb782e29b8b061" }, "responsed": false }, { "response": "GHI", "status": false, "_id": { "$oid": "64e460051cbb782e29b8b061" }, "responsed": false }, { "response": "JKL", "status": false, "_id": { "$oid": "64e460051cbb782e29b8b061" }, "responsed": false } ], "__v": { "$numberInt": "0" } }
期望更新结果
{ "_id": { "$oid": "64e460061cbb782e29b8b067" }, "threadId": { "$oid": "64e460061cbb782e29b8b065" }, "contactId": { "$oid": "64e460051cbb782e29b8b063" }, "status": true, "conversation": [ { "response": "ABC", "status": false, "_id": { "$oid": "64e460051cbb782e29b8b061" }, "responsed": true }, { "response": "DEF", "status": false, "_id": { "$oid": "64e460051cbb782e29b8b061" }, "responsed": true }, { "response": "GHI", "status": false, "_id": { "$oid": "64e460051cbb782e29b8b061" }, "responsed": true }, { "response": "JKL", "status": false, "_id": { "$oid": "64e460051cbb782e29b8b061" }, "responsed": true } ], "__v": { "$numberInt": "0" } }
当前代码(仅更新第一个元素)
await Conversations.updateOne( { threadId: "64e460061cbb782e29b8b065", "conversation.responsed": false }, { "conversation.$.responsed": true } );
Schema定义
const conversationsSchema = new schema({ threadId:{ type: schema.Types.ObjectId, ref: 'threads', unique: true }, contactId: { type: schema.Types.ObjectId, ref: 'contacts', unique: true }, status:{ type: Boolean, default: true }, conversation:[ { response: { type: String, required: false }, status: { type: Boolean, default: true }, responsed: { type: Boolean, default: false } } ] })
解决方案
原代码中使用的$操作符只会匹配数组中第一个符合查询条件的元素,因此无法批量更新所有符合条件的数组项。要实现批量更新,需要使用MongoDB的arrayFilters功能,配合$set操作符来指定要更新的元素:
await Conversations.updateOne( // 查询条件:匹配指定threadId的文档 { threadId: "64e460061cbb782e29b8b065" }, // 更新操作:将符合arrayFilters条件的元素的responsed设为true { $set: { "conversation.$[elem].responsed": true } }, // 数组筛选条件:匹配responsed为false的元素 { arrayFilters: [{ "elem.responsed": false }] } );
说明
arrayFilters定义了筛选规则"elem.responsed": false,其中elem是自定义的占位符,代表数组中符合条件的元素。- 更新语句中的
$[elem]会匹配所有符合arrayFilters条件的数组元素,从而实现批量更新。 - 确保你的Mongoose版本支持
arrayFilters(Mongoose 5.x及以上版本均支持)。
内容的提问来源于stack exchange,提问作者Krish
相关产品推荐
相关产品推荐

