如何在mongodb中更新多个数组对象 [英] How to Update Multiple Array objects in mongodb

查看:238
本文介绍了如何在mongodb中更新多个数组对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在mongodb中更新多个数组对象. 早些时候曾问过这个问题-如何更新多个数组元素在mongodb中

How to Update Multiple Array objects in mongodb. This question was asked earlier - How to Update Multiple Array elements in 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" : "....."
    }
        ...
]
}

我想将所有events.handled.visible:false更新为"events.handled.visible":true.

And I want to update all the events.handled.visible:false to "events.handled.visible":true.

我尝试了

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?

推荐答案

虽然我不认为迭代期望的计数是执行此操作的最佳"方法,但实际上,这是对您尝试执行的操作的更正在节点 async 用于流量控制的库的帮助下:

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.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
    }
  );

因此,这里的主要要点是您的.update()语句应查找"events.handled.visibile": false匹配项,当然,您需要确保操作按顺序"执行,否则不能真正保证您实际上是从以前的.update()抓取到处于更改状态的文档.

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().

async.whilst 处理流控制,以便它等待每个.update()直到执行下一个.当它的第一个逻辑语句是true(计数器已耗尽)并且所有.update()语句都运行时,循环将释放到最后的回调.

The async.whilst handles the flow control so that it waits for completion of each .update() until executing the next. 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.

您应该尽可能使用您要遵循的答案中提到的批量"更新操作.发送所有更新,一次且只有一个响应,因此消除了等待每个操作完成的开销.

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.

这篇关于如何在mongodb中更新多个数组对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆