MongoDB如何使用聚合管道更新多文档并按属性补全数组缺失项
MongoDB 聚合管道补全extension数组实现方案
匹配查询条件(q)
仅筛选需要更新的文档,已同时包含Name和Age项的文档会被自动排除,避免无意义写入:
q: { $or: [ { extension: { $exists: false } }, // 完全缺失extension字段 { "extension.key": { $ne: "Name" } }, // extension中无Name项 { "extension.key": { $ne: "Age" } } // extension中无Age项 ] }
更新聚合管道(u)
通过数组拼接逻辑,保留原有extension项的原值,仅补全缺失的默认项,最终顺序完全符合预期效果:
u: [ { $set: { extension: { $concatArrays: [ // 缺失Name时将默认项拼在数组最前方,已有则填空数组 { $cond: { if: { $anyElementTrue: { $map: { input: { $ifNull: [ "$extension", [] ] }, as: "ext", in: { $eq: [ "$$ext.key", "Name" ] } } } }, then: [], else: [ { key: "Name", value: "Default" } ] } }, // 保留原有extension内容,缺失则转空数组 { $ifNull: [ "$extension", [] ] }, // 缺失Age时将默认项拼在数组最后方,已有则填空数组 { $cond: { if: { $anyElementTrue: { $map: { input: { $ifNull: [ "$extension", [] ] }, as: "ext", in: { $eq: [ "$$ext.key", "Age" ] } } } }, then: [], else: [ { key: "Age", value: 99 } ] } } ] } } } ]
完整可执行命令(对应你使用的update结构)
db.runCommand({ update: "MyCollection", updates: [ { q: { $or: [ { extension: { $exists: false } }, { "extension.key": { $ne: "Name" } }, { "extension.key": { $ne: "Age" } } ] }, u: [ { $set: { extension: { $concatArrays: [ { $cond: { if: { $anyElementTrue: { $map: { input: { $ifNull: [ "$extension", [] ] }, as: "ext", in: { $eq: [ "$$ext.key", "Name" ] } } } }, then: [], else: [ { key: "Name", value: "Default" } ] } }, { $ifNull: [ "$extension", [] ] }, { $cond: { if: { $anyElementTrue: { $map: { input: { $ifNull: [ "$extension", [] ] }, as: "ext", in: { $eq: [ "$$ext.key", "Age" ] } } } }, then: [], else: [ { key: "Age", value: 99 } ] } } ] } } } ], multi: true // 批量更新所有匹配文档 } ] })
版本说明
聚合管道更新功能需要MongoDB 4.2及以上版本支持,低版本无法使用该写法。
内容的提问来源于stack exchange,提问作者Bruno
相关产品推荐
相关产品推荐

