在一个数据库调用中更新许多子文档

时间:2019-02-18 12:26:22

标签: javascript mongodb mongoose

如果我的文档包含对象数组。

Document = {
  _id: 1,
  doc_amount: 0,
  subDocsArray: [
  {      
   _id: 1,
   amount: 0   
  },
  {      
   _id: 2,
   amount: 1   
  },
  ...
 ]
}

我可以通过以下方式简单地增加doc_amount ...

Document.updateOne({ _id }, { $inc: { doc_amount: 1} })

但是增加subDocsArray中的数量比较棘手。如果我有一个Document.subDocsArray更新列表

var newSubDocsArray = [
  {      
   _id: 1,
   amount: 5   
  },
  {      
   _id: 2,
   amount: 5   
  },
]

如何在一次调用中增加Document.subDocsArray中的所有金额?请记住,newSubDocsArray可能并不总是包含subDocsArray中的每个项目,因此需要重新添加。

那有可能吗?

编辑: 为了清除问题,newSubDocsArray中的所有金额都可以是不同的值。每个现有subDoc数组项的数量应增加具有相同id的newSubDocs中的数量值。

3 个答案:

答案 0 :(得分:1)

您可以使用$[] array update oprator来实现:

db.getCollection("test").update(
  {_id:1},   
  {$inc:{"subDocsArray.$[].amount":1}}
)

答案 1 :(得分:1)

由于我没有真正回答上一个答案中的问题,因此这是一个新问题。

Afaik,您不能在Mongodb中的一个调用中执行此操作,但是您需要为每个新数组元素调用。然后,您可以使用arrayFilters更新与当前元素匹配的所有项目。这是一个行为不同的示例:

您的原始文档:

{ 
    "_id" : 1.0, 
    "doc_amount" : 0.0, 
    "subDocsArray" : [
        {
            "_id" : 1.0, 
            "amount" : 20.0
        }, 
        {
            "_id" : 2.0, 
            "amount" : 31.0
        }, 
        {
            "_id" : 3.0, 
            "amount" : 3.0
        }, 
        {
            "_id" : 5.0
        }
    ]
}

应用此脚本:

var newSubDocsArray = [
  {      
   _id: 1,
   amount: 3  
  },
  {      
   _id: 2,
   amount: 8   
  },
    {      
   _id: 4,
   amount: 7   
  },
      {      
   _id: 5,
   amount: 9   
  },
];


newSubDocsArray.forEach(function(newSubDoc){
  db.getCollection("test").update(
    {_id:1},   
    {$inc:{"subDocsArray.$[subdoc].amount":newSubDoc.amount}},   // Note the use of $[subdoc]
    { multi: true,
       arrayFilters: [ { "subdoc._id": newSubDoc._id } ]
    }
  )
})

结果:

{ 
    "_id" : 1.0, 
    "doc_amount" : 0.0, 
    "subDocsArray" : [
        {
            "_id" : 1.0, 
            "amount" : 23.0   // +3
        }, 
        {
            "_id" : 2.0, 
            "amount" : 39.0   // +8
        }, 
        {
            "_id" : 3.0, 
            "amount" : 3.0    // unchanged
        }, 
        {
            "_id" : 5.0, 
            "amount" : 9.0    // created, set to 9
        }
    ]
}

您可以注意到:

  • 具有_id 3的项目不会更新(不在新的newSubDocsArray中)。
  • 在数组中未创建
  • 具有_id 4的项目(arrayFilters不匹配任何内容)。
  • 具有_id 5的商品已创建一个新的金额字段。

答案 2 :(得分:-1)

您可以使用$ like来更新子数组项

首先给出条件{_id:1,'subDocsArray._id':1}

然后更新以下项目:{$ inc:{'subDocsArray。$。amount':1}}