MongoDB项目开发:如何按匹配条件为对象数组添加标志字段?
给MongoDB数组元素添加条件标志字段的解决方案
刚好做过类似的需求,给你两种实用的实现方式,看你是要修改原文档还是只在查询时返回结果:
方案一:批量更新原文档(推荐)
如果需要把所有符合条件的文档都永久修改,用updateMany结合聚合表达式就能搞定,不用在客户端循环处理,效率更高:
db.collection.updateMany( {}, // 这里可以加你的匹配条件,比如只更新特定_id的文档就写{_id: ObjectId("5aaa4eb211a1c1c1f74c1657")} [ { $set: { colors: { $map: { input: "$colors", as: "color", in: { $mergeObjects: [ "$$color", { $cond: [ { $eq: ["$$color.status", "done"] }, { is_in_production: true }, {} // 不满足条件就不添加字段 ] } ] } } } } } ] )
代码逻辑说明:
$map遍历colors数组里的每一个元素$mergeObjects把原元素对象和我们要添加的字段合并$cond做条件判断:如果元素的status等于"done",就添加is_in_production: true,否则添加空对象(也就是不新增字段)
方案二:聚合查询临时返回结果
如果不想修改原文档,只是查询时需要带这个标志字段,用aggregate的$addFields就可以:
db.collection.aggregate([ { $addFields: { colors: { $map: { input: "$colors", as: "color", in: { $mergeObjects: [ "$$color", { $cond: [ { $eq: ["$$color.status", "done"] }, { is_in_production: true }, {} ] } ] } } } } } ])
这个查询会返回你期望的结构,原文档的数据不会被改动,适合临时统计或者展示场景。
如果你的MongoDB版本低于4.2,可能不支持用聚合表达式做更新操作,那只能在客户端用forEach循环处理,但还是建议尽量升级版本用上面的方法,性能会好很多。
内容的提问来源于stack exchange,提问作者Bishwarup Das
相关产品推荐
相关产品推荐

