簡體   English   中英

使用Node.js進行回調遞歸插入Mongo

[英]Callback recursive insertion Mongo with Node.js

我正在使用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');

.save()是一個異步函數,因此for循環將在它們完成之前繼續運行它們。 這樣, i將比您預期的更快到達max速度。

換句話說,在所有father.save被解雇(未完成)之后, i達到max ,並且son.save將過早執行endInstall()

異步是一個庫來處理這種情況。 如果要繼續使用計數器,請查看times方法

就像是:

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

這樣,您可以確保一切都已完成。

在完成所有操作之前,這里需要調用endInstall方法。

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

與其嘗試使用for循環,不如使用異步庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM