在我的MongoDB / Node后端中,我有一个函数,该函数根据传入的订阅_id更新标题为subscriptionEnd的字段上的日期。看起来像这样:

    try {
      db.collection('clients').updateMany(
       { "subscription._id": { $in: mongoArrSubscription } },
       { $set : {"subscription.$.subscriptionEnd": lastDayOfMonth } },
        function (err, res) {
        if (err) throw err;
      });
      res.sendStatus(200);
    } catch (e) {
      console.log(e);
    }
  }


这是按原样工作的。但是,按原样,这将仅针对“预订”数组中的第一个元素。我意识到现在我们有了在同一数组中可以传入两个元素的实例。因此,我的想法是在此函数内使用$unwind,首先$ unwind“ subscription”数组。我在语法上还不清楚,这是否可行。

我的展开聚合看起来像这样:

Client.aggregate( [ { $unwind : "$subscription" } ] );


有什么方法可以将这个$unwind聚合链接在一起,以便它发生在try / catch块中的updateMany()之前?该语法是什么样的?是否将操作链接在一起,还是将$unwind作为参数传递给updateMany()

我尝试了此操作,将$ unwind操作作为第一个参数传入:

    try {
      db.collection('clients').updateMany( { $unwind : "$subscription" },
       { "subscription._id": { $in: mongoArrSubscription } },
       { $set : {"subscription.$.subscriptionEnd": lastDayOfMonth } },
        function (err, res) {
        if (err) throw err;
      });
      res.sendStatus(200);
    } catch (e) {
      console.log(e);
    }
  }


...但是它出错了:


  MongoError:未知修饰符:$ unwind


所以也许我需要先做$ unwind聚合,作为一个单独的操作,然后运行updateMany()

更新:有人指出$unwind不能与updateMany()一起使用,所以也许我需要先单独进行$unwind操作,然后再运行updateMany()操作?

最佳答案

您可以使用聚合和批量写入低版本的版本来模拟3.6多重更新。

就像是

var bulk = db.getCollection('clients').initializeUnorderedBulkOp();
var count = 0;
var batch = 1;

db.getCollection('clients').aggregate([
    {$match:{"subscription._id":{$in:mongoArrSubscription}}},
    {$unwind:"$subscription"},
    {$match:{"subscription._id":{$in:mongoArrSubscription}}},
    {$project: {_id:0, subscription_id:"$subscription._id"}}
]).forEach(function(doc){
    var subscription_id = doc.subscription_id;
    bulk.find({"subscription._id":subscription_id}).updateOne(
       {$set:{"subscription.$.subscriptionEnd": lastDayOfMonth}}
   );
    count++;
    if (count == batch) {
        bulk.execute();
        bulk = db.getCollection('clients').initializeUnorderedBulkOp();
        count = 0;
    }
});

if (count > 0) {
     bulk.execute();
}

10-05 17:42