MongoDB如何查找并更新嵌套数组中的匹配元素
原命令失效原因
原更新逻辑存在两处错误:
- 基础
$数组定位符仅能匹配查询条件命中的第一个数组元素,无法更新单文档内category数组下所有符合条件的元素 - 直接对
data.category.$整体赋值会覆盖该数组元素的全部字段,丢失原有name属性,同时将原本为数组类型的subcategory替换为字符串,破坏了原有数据结构。
正确实现方式
以下方案适用于MongoDB 3.6及以上版本,可精准替换所有嵌套数组中的目标值,不破坏原有数据结构:
db.employees.updateMany( // 筛选包含目标值的文档,减少不必要的更新扫描 { "data.category.subcategory": "EDUCATION" }, { $set: { "data.category.$[catElem].subcategory.$[subElem]": "SPORTS" } }, { // 定义数组过滤规则,定位所有符合条件的嵌套元素 arrayFilters: [ { "catElem.subcategory": "EDUCATION" }, { "subElem": "EDUCATION" } ] } )
命令说明
$[catElem]是数组过滤占位符,匹配category数组下所有subcategory包含EDUCATION的元素$[subElem]是二级数组占位符,匹配subcategory数组中值恰好为EDUCATION的项- 该命令会替换所有命中的目标值,保留文档内其他所有字段和非目标数组元素,同一个文档下多个符合条件的
category元素、同一个subcategory数组内的多个EDUCATION值都会被正确替换。
如果使用MongoDB 4.2及以上版本,也可以通过聚合管道更新实现相同效果:
db.employees.updateMany( { "data.category.subcategory": "EDUCATION" }, [ { $set: { "data.category": { $map: { input: "$data.category", as: "cat", in: { $mergeObjects: [ "$$cat", { subcategory: { $map: { input: "$$cat.subcategory", as: "sub", in: { $cond: [{ $eq: ["$$sub", "EDUCATION"] }, "SPORTS", "$$sub"] } } } } ] } } } } } ] )
内容的提问来源于stack exchange,提问作者Fahd Lihidheb
相关产品推荐
相关产品推荐

