使用Node.js回调递归插入Mongo

时间:2015-08-21 19:55:29

标签: javascript node.js mongodb recursion mongoose

我正在使用Node.js和MongoDB(Mongoose.js)进行API。我制作了一个“安装”脚本,用一些示例数据填充数据库,比如用户和其他东西。

问题是当我尝试添加递归插入时。

我将999个文档添加到一个集合(父亲),并为另一个集合(儿子)中的每个父文档添加12个文档。

父亲集合有999个文件。 但是当我期待Sons系列中的11988个文件时,儿子收藏只有1188个。

模型是正确的。我有很多单元测试来验证这些操作。

这是我的代码:

var mongoose = require('mongoose');
var conf = require('../config/dbConfig');
var fatherDb = require('../model/father');
var sonsDb = require('../model/son');
var db_lnk = conf.mongoSrv();
global.db = (global.db ? global.db : mongoose.createConnection(db_lnk));

function addFather(idSome, idOther){
    console.log("Adding Fathers");
    fatherDb.count({active:true}, function(err,count){
        if(!err){
            var max = (999-count);
            for(i=0; i<max; i++){
                var father = new fatherDb({
                    "name":"Father "  + (i+1),
                    "createdBy" : "55ad5f224f350c123b8e2bda",
                    "modifyBy" : "55ad5f224f350c123b8e2bda",
                    "active" : true,
                    "_some" : idSome,
                    "_other" : idOther,
                    "__v" : 0
                });
                father.save(function(err, data){
                    console.log("Adding 12 Sons to Father # " + i);
                    var idFather = data._id;
                    for (var x = 1; x < 13; x++) {
                        var son = new sonsDb({
                            "name": "Son " + x,
                            "position": x,
                            "createdBy": "55ad5f442f350c431b8e2bda",
                            "modifyBy": "55ad5f442f350c431b8e2bda",
                            "active": true,
                            "_father": idFather,
                            "__v": 0
                        });
                        son.save(function (err) {
                            console.log("Adding Son " + x);
                            if(i == max) {
                                endInstall();
                            }
                        });
                    }
                });
            }
        }else{
            console.log("Error");
            endInstall();
        }
    });
}

function endInstall(){
    console.log("Ending Installation");
    process.exit();
}

addFather('SOMEid','OtherId');

2 个答案:

答案 0 :(得分:1)

.save()是一个异步函数,因此for循环将在它们完成之前继续运行它们。这样i将比您预期的更早达到max

换句话说,i在所有max被解雇后未到达father.save,而son.save将过早执行endInstall()

async是一个处理这种情况的库。如果您想继续使用计数器,请查看times method

类似的东西:

// generate max fathers
async.times(max, function(n, next_father){
  var father = ...
  father.save(function(err){
    // generate 12 sons
    async.times(12, function(m, next_son){
      var son = ...
      son.save(function(err){
        next_son(err);
      });
    }, function(err, sons){
      next_father(err);
    });
  });
}, function(err, fathers) {
  // it's done
});

这样你可以确保一切都已完成。

答案 1 :(得分:0)

这一步在完成所有处理之前调用你的endInstall方法。

 son.save(function (err) {
    console.log("Adding Son " + x);
    if(i == max) {
      endInstall();
     }
    });
 }

使用异步库,而不是尝试使用for循环。