js:嵌套的MongoDB查询



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

在这个过程中,我在模型中引入了临时助手属性,以便找到相关的记录,并将它们替换为真实的MongoDB _ids。

  1. 脚本启动Sails是为了能够使用它的功能(水线等):

    var app = Sails();
    app.load({
      hooks: { grunt: false },
      log: { level: 'warn' }
    }, function sailsReady(err){
    
  2. processUsers()找到所有用户和他们的id,并在他们上迭代调用第二个函数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()查找属于此用户的所有组织并更新此用户的组织数组属性

    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');
                }); 
    
            });
        });
    }
    

问题:

  • Process.exit(0)在saddOrgsToOneUser()的查询/更新完成之前被调用。例如,如果saddOrgsToOneUser()只包含一个console.log,那么它的行为就像预期的那样,但是查询当然是异步触发的。
  • 如果我注释掉Process.exit(0),脚本永远不会停止,但是查询会按预期执行。
  • 由于脚本将有进一步嵌套查询,我需要一个更好的方法来手动杀死这个脚本…
  • 如何嵌套查询和迭代他们的结果正确完成?

非常感谢,Manuel

addOrgsToOneUser是异步的。next()需要在addOrgsToOneUser内部完成所有操作后调用。我要做的是传入一个回调(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
        }); 

    });
  });
}

相关内容

  • 没有找到相关文章

最新更新