如何使用猫鼬和异步瀑布模型在 MongoDb 中存储数据

Posted

技术标签:

【中文标题】如何使用猫鼬和异步瀑布模型在 MongoDb 中存储数据【英文标题】:How to store data in MongoDb using mongoose and async waterfall model 【发布时间】:2018-03-11 01:54:17 【问题描述】:

您好,我是 node 新手,我正在尝试将数据保存在 mongoose 中。问题是有 3 个集合 Units、Building 和 Section。 建筑的架构是:

var buildingsSchema=new Schema(
    buildingname:String,
    status:String
);

Section 的架构是:

var sectionsSchema=new Schema(
        section_type:String,
        buildings: type: Schema.Types.ObjectId, ref: 'buildings' ,
        status:String
 );

单位的架构是:

var unitsSchema=new Schema(
      unit_type:String,
      unit_num:String,
      unit_ac_num:Number,
      buildings: type: Schema.Types.ObjectId, ref: 'buildings' ,
      sections: type: Schema.Types.ObjectId, ref: 'sections' ,
      shares:Number
);

Section 中有 BuildingId,在 Units 中有 Building 和 SectionId's

现在我已经使用xlsx 插件将上传的 excel 文件转换为 json 格式:-

 var wb = XLSX.readFile("uploads/xls/" + req.file.filename);
 data = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]],   header:1);

并将其映射到 json 对象并保存我正在使用 异步瀑布模型

        for (var index = 1; index < data.length - 1 ; index++) 
        var ele= data[index];
        // console.log(ele);

        var d =    // this is an object which will hold data 
            record_id: ele[0],
            residenceone_unit_id : ele[1],
            official_unit_id: ele[2],
            building: ele[3],
            unit_type : ele[4],
            section: ele[5],
            shares: ele[6],
            unit_style : ele[7]
        
        // console.log(d);
        var unt = new Units(); // to save units
        unt = 
            unit_type: d.unit_type,
            unit_num: d.residenceone_unit_id,
            unit_ac_num: d.official_unit_id,
            buildings: '', // empty because need to put id of that particular building
            sections: '', // empty because need to put id of that particular sections
            shares:d.shares
        
        async.waterfall([
            function (callback) 
                // find building first 
                Buildings.findOne(buildingname : ele.building)
                .exec(function (err,doc) 
                      if (err) 
                          return callback(err);
                      
                      // if no building then save one 
                      else if (!doc) 
                        // console.log("Building is going to save")
                        var build = new Buildings();
                        build.buildingname = d.building;
                        build.status = "active";
                        build.save(function (err,dc) 
                            if (err) 
                                return callback(err);
                            
                            else 
                                // assign id of building to unit
                                unt.buildings = dc._id ;
                                callback(null);
                            
                        )
                       
                      else 
                        // if building is there then no need to save assign id of it to units
                        // console.log("Building already exists;")
                         unt.buildings = doc._id ;
                         // execute second function
                         callback(null);
                       
                    //   callback(null);
                )
            ,
            function (callback) 
                // same as building find section of that building first with building Id and section type
                Sections.findOne(buildings : unt.buildings,section_type: d.section)
                    .exec(function (err,doc) 
                      if (err) 
                          return callback(err);
                      
                      if (!doc) 
                        // if no section of that building is there then save one
                        // console.log("Section needs to be save")
                        var sect = new Sections();
                        sect.section_type = d.section;
                        sect.buildings = unt.buildings;
                        sect.status = "active";
                        sect.save(function (err,dc) 
                            if (err) 
                                return callback(err);
                            
                            else 
                                // assign its id to unit
                                // console.log("Section is saved")
                                unt.sections = dc._id; 
                                // execute third function
                                callback(null); 
                            
                        )
                       
                      else 
                          // if there is section of that building id is available than assign id to units
                        // console.log("Section already exists");
                        unt.sections = doc._id;
                         // execute third function 
                         callback(null);  
                      
                )
            ,
            function (callback) 
                // there is no need to seaarch just need to save unit
                // console.log("Units is going to save")
                // console.log(unt);
                unt.save(function (err, doc) 
                    if (err) 

                     else if (doc)
                        // console.log("Unit Saved");
                        // console.log(doc);

                    

                )
            
         ])
    

它可以工作,但每次都不是在 mongodb 中搜索数据,而是每次都保存。如果在 mongodb 中保存单位的任何其他方法对我有很大帮助,重复是主要问题。

【问题讨论】:

嗨,我认为您的问题是这样的。 Buildings.findOne(buildingname : ele.building) ele.building 不存在您正在搜索未定义您需要使用 d.building 兄弟,它工作正常,只是问题是数据被一次又一次地插入,而我的实际数据来自数组 您应该使用async.eachSeries()(或者可能是async.eachLimit),而不是使用for (var index = 1; ...) 好吧,我试着让您知道 ROBERTKLEP 先生 我试过了,但它是 console.log(units) 然后在找到一个在建筑中的文件之后 【参考方案1】:

首先我保存了建筑物和部分

async.every(uniqueSection,function (uS,callback) 
      if (uS != undefined) 
          console.log(uS);
            Buildings.findOne(buildingname:uS.building, function (err,doc) 
                if (doc) 
                    // console.log(doc);
                    Sections.findOne(buildings:doc._id,section_type:uS.section,function (er,sd) 
                        if (sd) 
                            // then dont save
                            console.log(sd);
                        
                        if (er) 
                            console.log(er);
                        
                        if (!sd) 
                            // then save
                            var sect = new Sections();
                            sect.buildings = doc._id;
                            sect.section_type = uS.section;
                            sect.status = 'active';
                            sect.save(function (err,st) 
                                if(err) console.log(err);
                                console.log(st);
                            )
                        
                    )  
                 
                if (!doc) 
                 if (uS.building != undefined) 
                    var building = new Buildings();
                    building.buildingname = uS.building;
                    building.status = "active";
                    building.save(function (er,dc) 
                        if (dc) 
                            // console.log(dc);
                            Sections.findOne(buildings:dc._id,section_type:uS.section,function (er,sd) 
                                if (sd) 
                                    // then dont save
                                    console.log(sd);
                                
                                if (er) 
                                    console.log(er);
                                
                                if (!sd) 
                                    // then save
                                    var sect = new Sections();
                                    sect.buildings = dc._id;
                                    sect.section_type = uS.section;
                                    sect.status = 'active';
                                    sect.save(function (err,st) 
                                        if(err) console.log(err);
                                        console.log(st);
                                    )
                                
                            )  
                         
                        if (er) 
                            console.log(er);
                        
                    )
                  
                
                if (err) 
                    console.log(err);
                
              )
            
        )

然后我保存了 Units

   async.waterfall([
                function(callback) 
                    Buildings.findOne(buildingname:d.building, function (err,doc) 
                        if (doc) 
                            buildingId = doc._id;
                            callback(null, doc);
                         
                        if (err) 
                            console.log(err);
                        
                      )

                ,
                function(doc,callback) 
                    Sections.findOne(buildings: buildingId,section_type:d.section,function (er,sd) 
                        if (sd) 
                            sectionId = sd._id;
                           callback(null,doc,sd);  
                        
                        if (er) 
                            console.log(er);
                        

                    )  
                ,
                function (bld,st,callback) 
                var s = d.shares.replace(",","");
                var unit = 
                    unit_type: d.unit_type,
                    unit_num: d.residenceone_unit_id,
                    unit_ac_num: d.official_unit_id,
                    buildings: bld._id, 
                    sections: st._id,
                    shares: s
                 
                 Units.findOne(unit,function (err,unt) 
                     if (err) 
                         console.log(err);
                      
                     if(unt) 
                         console.log(unt)
                     
                     if (!unt) 
                        var units = new Units();
                        units.unit_type = d.unit_type;
                        units.unit_num = d.residenceone_unit_id;
                        units.unit_ac_num = d.official_unit_id;
                        units.buildings = bld._id; 
                        units.sections = st._id;
                        units.shares = s;

                        units.save(function (er,doc) 
                            if (er) console.log(er);
                            console.log(doc);
                        ) 
                     
                 )
                
            ], function(err) 
                console.log(err)
            );

【讨论】:

以上是关于如何使用猫鼬和异步瀑布模型在 MongoDb 中存储数据的主要内容,如果未能解决你的问题,请参考以下文章

带有异步队列和瀑布的猫鼬

如何在猫鼬和节点js中的同一记录上填充两个集合

如何使用猫鼬和EJS实现分页并在分页时保留搜索查询?

猫鼬和浮点值

使用猫鼬和nestJS自动增加字段

如何定义适用于猫鼬和graphql的模式