简体   繁体   English

如何在mongodb中更新多个数组对象

[英]How to Update Multiple Array objects in mongodb

How to Update Multiple Array objects in mongodb. 如何在mongodb中更新多个数组对象。 This question was asked earlier - How to Update Multiple Array elements in mongodb 前面曾问过这个问题- 如何在mongodb中更新多个数组元素

But that didn't work for me. 但这对我没有用。 I have an array of objects 我有一系列对象

{
    "_id" : ObjectId("4d2d8deff4e6c1d71fc29a07"),
    "user_id" : "714638ba-2e08-2168-2b99-00002f3d43c0",
    "events" : [
    {
        "handled" : {
            "name": "Mike",
            "visibile": false
        },
        "profile" : 10,
        "data" : "....."
    }
    {
        "handled" : {
            "name": "Shaun",
            "visibile": false
        },
        "profile" : 10,
        "data" : "....."
    }
    {
        "handled" : {
            "name": "Glen",
            "visibile": true
        },
        "profile" : 20,
        "data" : "....."
    }
        ...
]
}

And I want to update all the events.handled.visible:false to "events.handled.visible":true. 我想将所有events.handled.visible:false更新为“ events.handled.visible”:true。

I tried 我试过了

collection.aggregate({
      $match: {
        _id: ObjectId("4d2d8deff4e6c1d71fc29a07")
      }
    }, {
      $unwind: "$events"
    }, {
      "$match": {
        "events.handled.visible": false
      }
    }, {
      "$group": {
        "_id": "$_id",
        "count": {
          "$sum": 1
        }
      }
    }, {
      "$group": {
        "_id": null,
        "count": {
          "$max": "$count"
        }
      }
    }, function(err, res) {
      var max = res[0].count;
      while (max--) {
        collection.update({
          "events.handled.visible": 1
        }, {
          "$set": {
            "events.$.handled.visible": true
          }
        }, {
          "multi": true
        }, function(err, res) {
          if (err) {
            console.log("Whoops! " + err)
          } else {
            console.log("Yay! " + res)
          }
        })
      }
    } //End Function
  ) //End Aggregate

But that didn't update anything. 但这并没有更新任何内容。 What am I missing? 我想念什么?

While I don't think that iterating over an expected count is the "best" way to do this, here is basically the corrections to what you are trying to do, with some help by the node async library for flow control: 虽然我不认为迭代期望的计数是执行此操作的“最佳”方法,但基本上是对您尝试执行的操作的更正,并借助节点async库对流进行控制:

  async.waterfall(
    [
      function(callback) {
        collection.aggregate(
          [
            { "$match": { "_id": ObjectId("4d2d8deff4e6c1d71fc29a07") } },
            { "$unwind": "$events" },
            { "$match": { "events.handled.visibile": false } },
            { "$group": {
              "_id": "$_id",
              "count": { "$sum": 1 }
            }}
          ],
          callback
        );
      },

      function(results,callback) {
        console.log(results);
        var result = results[0];

        async.whilst(
          function() { return result.count-- },
          function(callback) {
            collection.update(
              { "_id": result._id, "events.handled.visibile": false },
              { "$set": { "events.$.handled.visibile": true } },
              callback
            )
          },
          callback
        );
      }
    ],
    function(err) {
      if (err) throw err;
      // finished now
    }
  );

So the main things here are that your .update() statement should instead be looking for the "events.handled.visibile": false matches, and of course you need to make sure the operations execute "in series", otherwise there is no real guarantee that you are in fact grabbing the document in an altered state from the previous .update() . 因此,这里的主要内容是您的.update()语句应改为查找"events.handled.visibile": false匹配,当然,您需要确保操作“按"events.handled.visibile": false执行,否则就没有了真正保证您实际上是在与先前的.update()相比.update()更改状态的文档。

The async.whilst handles the flow control so that it waits for completion of each .update() until executing the next. async.whilst处理流控制,以便它等待每个.update()完成,直到执行下一个。 When it's first logical statement is true ( counter depleted ) and all .update() statements are run then the loop will release to the final callback. 当它的第一个逻辑语句为true (计数器已耗尽)并且所有.update()语句都运行时,循环将释放到最终的回调。

Where possible you should really be using "Bulk" update operations as referenced in the answer that you are following . 在可能的情况下,您实际上应该按照所遵循答案中的说明使用“批量”更新操作。 That sends all updates and once and only has one response, so the overhead of waiting for each operation to complete is eliminated. 它将发送所有更新,并且一次且只有一个响应,因此消除了等待每个操作完成的开销。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM