您应该能够使用 forEach() 方法遍历 Answers 集合中的每个答案文档,通过在 Users 集合中搜索 id 来找到相关的用户文档,如在以下示例中:
Answers = new Meteor.Collection("answers");
Users = new Meteor.Collection("users");
if(Meteor.isClient) {
processed_data = [];
Deps.autorun(function (c) {
console.log('run');
var cursor = Answers.find({}, { sort: { time: 1 }});
if (!cursor.count()) return;
cursor.forEach(function (ans) {
var user = Users.findOne({ "_id": ans.user }, { "fields": {"firstname": 1, "surname": 1} });
ans.user = user;
processed_data.push(ans);
});
console.log(processed_data);
c.stop();
});
}
数据将是响应式的,因为当您使用 Deps.autorun 时,function() {...} 中的整个块将在每次响应式变量或文档以任何方式发生变化时重新运行(即更新、删除或插入),或任何其他反应性变量更改。
至于使用具有名字和姓氏的实际用户文档更新Answers集合中的userId的其他解决方案,您可以通过使用Bulk API operations 进行更新。您可以通过 Mongo.Collection 上的 rawCollection() 和 rawDatabase() 方法获取对 npm MongoDB 驱动程序中的集合和数据库对象的原始访问权限.
Answers = new Meteor.Collection("answers");
Users = new Meteor.Collection("users");
if (Meteor.isClient) {
Template.answerlist.helpers({
answers: function () {
processed_data = [];
Deps.autorun(function (c) {
console.log('run');
var cursor = Answers.find({}, { sort: { time: 1 }});
if (!cursor.count()) return;
cursor.forEach(function (ans) {
var user = Users.findOne({ "_id": ans.user }, { "fields": {"firstname": 1, "surname": 1} });
ans.user = user;
processed_data.push(ans);
});
console.log(processed_data);
c.stop();
});
return processed_data;
}
});
Template.answerlist.events({
'click #updateAnswers': function(ev) {
Meteor.call('updateAnswersUser');
}
});
}
if (Meteor.isServer) {
Meteor.startup(function () {
Meteor.methods({
updateAnswersUser: function() {
var bulkOp = Answers.rawCollection().initializeUnorderedBulkOp(),
counter = 0;
Answers.find({}).forEach(function(ans) {
var user = Users.findOne({ "_id": ans.user }, { "fields": {"firstname": 1, "surname": 1} });
var changes = {};
changes["user"] = user;
bulkOp.find({"_id": ans._id}).updateOne({ "$set": changes });
counter++;
if (counter % 1000 == 0) {
// Execute per 1000 operations and re-initialize every 1000 update statements
bulkOp.execute(function(e, r) {
console.info('r.nMatched', r.nMatched, 'r.nModified', r.nModified);
});
bulkOp = Answers.rawCollection().initializeUnorderedBulkOp();
}
});
// Clean up queues
if (counter % 1000 != 0){
bulkOp.execute(function(e, r) {
console.info('r.nMatched', r.nMatched, 'r.nModified', r.nModified);
});
}
}
});
});
}