如何更新MongoDB中数组元素全为指定值的文档状态?
问题:批量更新MongoDB中满足条件的文档状态
需求说明
更新所有approvers数组内全部元素的status均为'approved'的文档,将文档自身的status字段设为'completed'
原始数据结构
[ { _id: 'asdasd', status: 'active', approvers: [ {status: 'approved'}, {status: 'approved'} ] }, { _id: 'fghfgh', status: 'active', approvers: [ {status: 'approved'}, {status: 'awaiting_approval'}, ] } ]
尝试过的复杂聚合查询(筛选有效但更新失败)
db.getCollection("assignmentRequest").aggregate([ { $match: { 'approver.0.status': {$exists:true} } }, { $project: { _id: 0, approver: 1, status: 1, noOfApprovers: { $cond: { if: { $isArray: "$approvers" }, then: { $size: "$approvers" }, else: 0}}, noOfApproversThatHasApproved: { $size: {$filter: { 'input': '$approvers', 'as': 'approver', 'cond': { '$and': [ { $eq: ['$$approver.status', 'approved'] } ] } }} }, }, }, { $match: {$expr: { $eq: ["$noOfApprovers", "$noOfApproversThatHasApproved"] } } }, { $set: {'status': 'completed'} }, { $project: {_id:1, status:1 } }, { $merge: {into: 'assignmentRequests_copy', on: '_id', whenMatched: "replace" } }])
期望更新后的结果
[ { _id: 'asdasd', status: 'completed', approvers: [ {status: 'approved'}, {status: 'approved'} ] }, { _id: 'fghfgh', status: 'active', approvers: [ {status: 'approved'}, {status: 'awaiting_approval'}, ] } ]
简洁解决方案
直接使用updateMany结合精准查询条件,无需复杂聚合操作:
db.getCollection("assignmentRequest").updateMany( { // 确保数组存在且非空 approvers: { $exists: true, $ne: [] }, // 筛选出所有approvers元素的status均为'approved'的文档 $not: { $elemMatch: { status: { $ne: "approved" } } }, // 可选:仅更新当前状态为active的文档,避免重复操作 status: "active" }, // 更新文档自身状态为completed { $set: { status: "completed" } } )
方案说明
- 用
$not: { $elemMatch: { status: { $ne: "approved" } } }精准筛选:不存在任何一个approver的status不等于approved,即所有元素都满足status: 'approved' - 直接通过
updateMany完成筛选+更新,逻辑清晰且性能更优,无需额外的聚合merge步骤 - 可选的
status: "active"条件可以避免重复更新已完成的文档
内容的提问来源于stack exchange,提问作者Marc Wihlstrand
相关产品推荐
相关产品推荐

