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

Node.js 如何在mongodb中更新多个数组对象,node.js,mongodb,mongodb-query,Node.js,Mongodb,Mongodb Query,如何在mongodb中更新多个数组对象。 这项质询较早前提出: 但这对我不起作用。我有一个对象数组 { "_id" : ObjectId("4d2d8deff4e6c1d71fc29a07"), "user_id" : "714638ba-2e08-2168-2b99-00002f3d43c0", "events" : [ { "handled" : { "name": "Mike", "visibi

如何在mongodb中更新多个数组对象。 这项质询较早前提出:

但这对我不起作用。我有一个对象数组

{
    "_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

我试过了

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

但这并没有更新任何东西。我遗漏了什么?

虽然我不认为对预期计数进行迭代是实现这一点的“最佳”方法,但这里基本上是对您尝试执行的操作的更正,在节点库的帮助下实现流控制:

  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.visible”:false
匹配项,当然您需要确保操作“串联”执行,否则,无法真正保证您实际上是从先前的
.update()
中以更改的状态获取文档

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


在可能的情况下,您应该真正使用中引用的“批量”更新操作。它发送所有更新,一次且只有一个响应,因此消除了等待每个操作完成的开销。

{code>{“events.handled.visible”:1}应该是
{“events.handled.visible”:false}
。不确定您认为额外的
$group
阶段应该做什么。作为你在链接帖子上关注的答案的作者,你没有遵循“不要假设”的规则,只是试图更新
n次。最好在没有返回更新计数之前进行更新。通过这种方式,您可以确保所有内容都是
false
。此外,在循环中使用异步方法进行循环是不好的。您应该使用一个循环,该循环只在内部
.update()
的回调上迭代,这样您就不会对实际并行执行的操作排队,而不是按照您的操作所期望的串行顺序排队。当我尝试按多个条件匹配时,为什么更新不起作用?例如:{“events.handled.visible”:false,“events.handled.name”:{$ne:null}}没有更新任何内容。这将是另一个问题。当你有更多的问题时,你可以回答。但只要读一读该做什么就行了。这取决于你在哪里使用它。这将是“在”
$unwind
之前”,但“在”之后不适用。