在我的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();
}