我有一个 Documents
在...中 Collection
的字段,该字段是一个 Array
(foo)。这是一个 Array
其他 subdocuments
. 我想为每一个人设置相同的字段(条形)。subdocument
在每 document
到相同的值。这个值来自于一个复选框。
所以...我的客户端代码是这样的
'click #checkAll'(e, template) {
const target = e.target;
const checked = $(target).prop('checked');
//Call Server Method to update list of Docs
const docIds = getIds();
Meteor.call('updateAllSubDocs', docIds, checked);
}
我试着用 https:/docs.mongodb.commanualreferenceoperatorupdatepositional-all#positional-update-all。
并为我的Server helper方法做了如下处理。
'updateAllSubDocs'(ids, checked) {
Items.update({ _id: { $in: ids } }, { $set: { "foo.$[].bar": bar } },
{ multi: true }, function (err, result) {
if (err) {
throw new Meteor.Error('error updating');
}
});
}
但是,这抛出了一个错误'foo.$[].bar is not allowed by the Schema'。我在父文档和子文档中都使用了SimpleSchema。
谢谢!所以我有一些客户端的代码,需要对一个文档数组进行更新。
尝试传递一个选项来绕过简单模式。它可能缺乏对这个(有点)较新的Mongo功能的支持。
bypassCollection2
举个例子。
Items.update({ _id: { $in: ids } }, { $set: { "foo.$[].bar": bar } },
{ multi: true, bypassCollection2: true }, function (err, result) {
if (err) {
throw new Meteor.Error('error updating');
}
});
老答案。
既然你说你需要为每个文档做一个独特的更新,听起来在这种情况下,批量更新是最好的方式。这里有一个例子说明如何在Meteor中做到这一点。
if (docsToUpdate.length < 1) return
const bulk = MyCollection.rawCollection().initializeUnorderedBulkOp()
for (const myDoc of docsToUpdate) {
bulk.find({ _id: myDoc._id }).updateOne({ $set: update })
}
Promise.await(bulk.execute()) // or use regular await if you want...
注意,如果没有文档,我们会提前退出函数,因为 bulk.execute()
如果没有操作要处理,会抛出异常。
如果你的数据在数组上的每个条目的$set中都有不同的数据,我想你需要在服务器端进行循环。
Mongo有Bulk操作,但我不知道你是否可以使用 Collection.rawCollection().XXXXX
我用过 rawCollection()
来访问聚合,我觉得很好用。也许可以配合批量操作。