将属性添加到文档中目标属性是数组无法正常工作的地方

时间:2018-10-09 14:31:50

标签: arrays mongodb

我正在尝试将属性添加到数组中每个元素的集合中每个文档的属性。经过研究后,这似乎是可行的方法:

db.customers.update(
   { "subscriptions": { "$elemMatch": { "subscriptions._id" : { $exists: true } } } }, 
   { "$set": { "subscriptions.deleted": false } },
   { "multi": true }
)

我认为这将是在存在“ _id”道具(将是每个)的“ subscriptions”数组中找到每个元素。然后它将“ deleted”属性添加到这些元素中的每个元素上,并且对所有文档都执行此操作,因为“ multi”设置为“ true”。

但是,这似乎没有达到预期的效果。我的结果是:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })

我这里缺少什么吗?

这是数据的样子:

{
  _id: 333,
  nameFirst: 'John',
  nameLast: 'Smith',
  subscriptions: [
     { _id: 555,
       someProp: 'abc'
     },
     { _id: 556,
       someProp: 'def'
     },
  ],
  email: 'john@email.com'
}

...这就是我要完成的工作:

{
  _id: 333,
  nameFirst: 'John',
  nameLast: 'Smith',
  subscriptions: [
     { _id: 555,
       someProp: 'abc',
       deleted: false // This is the prop I want to add to each element
     },
     { _id: 556,
       someProp: 'def',
       deleted: false // This is the prop I want to add to each element
     },
  ],
  email: 'john@email.com'
}

1 个答案:

答案 0 :(得分:1)

您可以在MongoDB 3.6中使用$[identifier](位置过滤)运算符来更新多个指定匹配条件的数组元素:

db.customers.update(
   { }, 
   { "$set": { "subscriptions.$[cond].deleted": false } },
   { "multi": true, arrayFilters: [{ "cond._id": { $exists: true } }] }
)

对于较低的MongoDB版本,您可以使用$out运算符,该运算符可以将现有集合替换为聚合结果。试试:

db.customers.aggregate([
    {
        $addFields: {
            subscriptions: {
                $map: {
                    input: "$subscriptions",
                    as: "sub",
                    in: {
                        $cond: {
                            if: { $gt: [ "$$sub._id", null] },
                            then: { _id: "$$sub._id", someProp: "$$sub.someProp", deleted: false },
                            else: "$$sub"
                        }
                    }
                }
            }
        }
    },
    { $out: "customers" }
])

使用$map$addFields覆盖现有的subscriptions$gt来检查字段是否存在。