Sails.js:嵌套的MongoDB查询

我正在使用Sails v0.11,并且正在开发一个独立的导入脚本,以便将数据导入到mongoDB中 – 现在是非工作部分 – build立模型之间的关联。

对于这个过程,我在模型中引入了临时助手属性,以便查找关联的logging,并用真实的MongoDB _idsreplace它们。

  1. 该脚本启动Sails以便能够使用其function(水线等):

    var app = Sails(); app.load({ hooks: { grunt: false }, log: { level: 'warn' } }, function sailsReady(err){ 
  2. processUsers()查找所有用户及其_ids并遍历它们以调用第二个函数addOrgsToOneUser()

     var processUsers = function() { // Iterate through all users in order to retrieve their _ids and app.models['user'].native(function(err, collection) { collection.find({}, projectionOrgInUser).toArray(function (err, users) { Async.eachSeries(users, function (user, next){ // prepare userInOrgs whereUserInOrg = { orgId: { $in: userInOrgs } }; //This is invoking addOrgsToOneUser(user, whereUserInOrg); next(); }, function afterwards (err) { if (err) { console.error('Import failed, error details:\n',err); return process.exit(1); } console.log("done"); return process.exit(0); // This returns too early, not executing the addOrgsToOneUser }); }); }); }; 
  3. addOrgsToOneUser()查找属于这个用户的所有组织,然后更新这个用户的orgs数组属性

     var addOrgsToOneUser = function(user, whereUserInOrg) { var projectionUserInOrg = "..."; // Find all orgs that this user is associated to and store it in inOrgs app.models['org'].native(function(err, collection) { collection.find(whereUserInOrg, projectionUserInOrg).toArray(function (err, orgs) { // prepare inOrgs which is needed for updating //update user to have an updated orgs array based on inOrgs. app.models['user'].update({'id' : user._id.toString()}, {'orgs': inOrgs}).exec(function afterwards(err, updated){ console.log('Updated user ' + user._id.toString() + ' to be in their orgs'); }); }); }); } 

问题:

  • 在saddOrgsToOneUser()的查询/更新完成之前调用Process.exit(0)。 如果saddOrgsToOneUser()仅包含一个console.log,但它的行为与预期相同,但查询当然是同步触发的。
  • 在我注释掉Process.exit(0)的情况下,脚本永远不会停止,但查询按照执行。
  • 由于该脚本将进一步嵌套查询,我需要一个更好的方法来手动杀死这个脚本…
  • 如何嵌套查询并迭代正确地完成结果?

非常感谢,曼努埃尔

addOrgsToOneUser是asynchronous的。 在addOrgsToOneUser内完成所有事情之后,next()需要被调用。 我会这样做的方式是传递一个callback(next),并在一切完成时调用它。 所以电话是

 addOrgsToOneUser(user, whereUserInOrg, next); 

而addOrgsToOneUser将会有一个额外的参数:

 var addOrgsToOneUser = function(user, whereUserInOrg, callback) { var projectionUserInOrg = "..."; // Find all orgs that this user is associated to and store it in inOrgs app.models['org'].native(function(err, collection) { collection.find(whereUserInOrg, projectionUserInOrg).toArray(function (err, orgs) { // prepare inOrgs which is needed for updating //update user to have an updated orgs array based on inOrgs. app.models['user'].update({'id' : user._id.toString()}, {'orgs': inOrgs}).exec(function afterwards(err, updated){ console.log('Updated user ' + user._id.toString() + ' to be in their orgs'); callback(); // your original next() is called here }); }); }); }