我正在学习 express 和 mongoose,我无法保存要保存的模式,但可以通过 console.log() 看到它

Posted

技术标签:

【中文标题】我正在学习 express 和 mongoose,我无法保存要保存的模式,但可以通过 console.log() 看到它【英文标题】:I am learning express and mongoose and I cannot get a schema to save, but can see it with console.log() 【发布时间】:2020-01-20 12:29:03 【问题描述】:

编辑:我认为 weekCount 在记录加载到其中之前正在保存。可能不正确地使用 find()?

我创建了一个网站来记录营地(围场)中的动物。我正在使用 express、mongo、mongoose 和 pug。

我有一个模式(见下文),它有一个类型数组:Schema.Types.ObjectId,我无法保存到 mongo。数组为空。

我有一个表格,可以获取营地名称和动物类型(奶牛、公牛、小牛)并创建一个表格。

表单显示出来,POST可以读取表单数据。表单数据被读入架构并使用console.log显示正常,但不会将整个架构保存在mongo中。

我已经阅读了很多帖子,并尝试了很多东西,例如 markModified,使用了完整的 Schema。

现在已经几个小时了,我希望能得到一些帮助。

Express mongoose 模型:

var WeekCountSchema = new Schema(
  dateOfCount:  type: Date ,
  campCounts: [type: Schema.Types.ObjectId, ref: 'CampCount']  < ----- problem
);

var CampCountSchema = new Schema(
      campName: String,
      campCountDate: Date,
      count: 
        ox: Number,
        cow: Number,
        bull: Number,
        heifer: Number,
        calf: Number,
        weaner: Number
      
);
weekCountController:
Scroll Down to the <---- 

exports.weekCount_create_post = [

  validator
    .body("dateOfCount", "Week Count Data Required")
    .toDate()
    .isLength( min: 1 )
    .trim(),


  validator.sanitizeBody("*").escape(),


  (req, res, next) => 
    var weekCount = new WeekCount(
      dateOfCount: req.body.dateOfCount
    );


    const errors = validator.validationResult(req);

    if (!errors.isEmpty()) 
      // There are errors. Render the form again with sanitized values/error messages.
      console.log("ERRORS!s");
      async.parallel(
        
          camps: function(callback) 
            Camp.find()
              .sort("name")
              .exec(callback);
          ,
          cattleClasses: function(callback) 
            CattleClass.find(callback);
          
        ,
        function(err, results) 
          if (err) 
            return next(err);
          
          res.render("weekCount_form", 
            title: "There were Errors! New Week Count",
            camps: results.camps,
            cattleClasses: results.cattleClasses
          );
        
      );

      return;
     else 
      // Data from form is valid.


      Camp.find(, "name").exec(function(err, list_camps) 
        if (err) 
          return next(err);
        

        CattleClass.find(, "name").exec(function(err, list_cattleClasses) 
          if (err) 
            return next(err);
          

          var campCountArray = [];
          list_camps.forEach(function(campName) 
            var campCount = new CampCount(
              campName: campName.name
            );

            var emptyCount = true;
            list_cattleClasses.forEach(function(cattleClassName) 
              var tempVar = campName.name + "." + cattleClassName.name;
              var tempNum = parseInt(req.body[tempVar]);
              // console.log(tempNum);
              if (tempNum) 
                // console.log(req.body[tempVar]);
                campCount.count[cattleClassName.name] = req.body[tempVar];
                emptyCount = false;
               else 
                campCount.count[cattleClassName.name] = 0;
              
            );

            if (!emptyCount) 
              campCount.save(function(err) 
                if (err) 
                  return next(err);
                
              );

              campCountArray.push(campCount);
            
          );
          console.log("CampCountArray");
          console.log(campCountArray);
          weekCount.campCounts = campCountArray;
        );
      );

      // ****************************************************************
      // Check if Week Count with same date already exists.
      WeekCount.findOne( dateOfCount: req.body.dateOfCount ).exec(function(
        err,
        found_weekCount
      ) 
        if (err) 
          console.log("ERROR findone " + err);
          return next(err);
        
        if (found_weekCount) 
          // Week count exists, redirect to its detail page.
          console.log("FOUND");
          res.redirect(found_weekCount.url);
         else 
          console.log("NOT FOUND");
          // weekCount.markModified('campCounts');
          weekCount.save(function(err)             // <---- does not save 
            if (err) 
              console.log("ERROR SAVING: " + err);
              return next(err);
            
            console.log("weekCount saved");
            console.log(weekCount);
            // output below

            // Week Count saved. Redirect to week count detail page.

            //   console.log(weekCount.campCounts);
            res.redirect(weekCount.url);

          );
        
      );
    
  
];

console.log 的输出:

GET /catalog/WeekCount/create 200 219.085 ms - 3782
NOT FOUND  <------ count not a duplicate (OK)
CampCountArray
[  count:  calf: 1, bull: 0, cow: 0, weaner: 0, ox: 0, heifer: 0 ,
    _id: 5d83720e2279011e90a1614b,
    campName: 'Bloekom' ,
   count:  calf: 1, bull: 0, cow: 0, weaner: 0, ox: 0, heifer: 0 ,
    _id: 5d83720e2279011e90a1614c,
    campName: 'Davel' ,
   count:  calf: 1, bull: 0, cow: 0, weaner: 0, ox: 0, heifer: 0 ,
    _id: 5d83720e2279011e90a1614d,
    campName: 'Elfas' ,
   count:  calf: 1, bull: 0, cow: 0, weaner: 0, ox: 0, heifer: 0 ,
    _id: 5d83720e2279011e90a1614e,
    campName: 'Groot kamp'  ]
weekCount saved
 campCounts: 
   [  count: [Object],
       _id: 5d83720e2279011e90a1614b,
       campName: 'Bloekom',
       __v: 0 ,
      count: [Object],
       _id: 5d83720e2279011e90a1614c,
       campName: 'Davel',
       __v: 0 ,
      count: [Object],
       _id: 5d83720e2279011e90a1614d,
       campName: 'Elfas',
       __v: 0 ,
      count: [Object],
       _id: 5d83720e2279011e90a1614e,
       campName: 'Groot kamp',
       __v: 0  ],
  _id: 5d83720e2279011e90a1614a,
  dateOfCount: 2019-09-06T00:00:00.000Z,
  __v: 0 

来自蒙哥:


        "_id" : ObjectId("5d83720e2279011e90a1614a"),
        "campCounts" : [ ],  <---------------------- nothing here!
        "dateOfCount" : ISODate("2019-09-06T00:00:00Z"),
        "__v" : 0

campCounts 在 mongo 中(示例):



        "_id" : ObjectId("5d83720e2279011e90a1614d"),
        "count" : 
                "calf" : 1,
                "bull" : 0,
                "cow" : 0,
                "weaner" : 0,
                "ox" : 0,
                "heifer" : 0
        ,
        "campName" : "Elfas",
        "__v" : 0

但是 weekCount 没有更新。这就是问题所在。

【问题讨论】:

【参考方案1】:

我认为您的怀疑是正确的,即 weekCount 在 CattleClass.find() 回调完成执行之前保存。

您可以使用 .then 语法解决此问题:

CattleClass.find(, "name").exec(function(err, list_cattleClasses) 

...     

).then( function () 
  WeekCount.findOne( dateOfCount: req.body.dateOfCount ).exec(function(
  err, found_weekCount) 

  ...

  
)

你也可以使用 ES6 async/await 语法,但是你的代码需要大量的重写,因为你不能在 await 中使用 .exec()。

这两种方法都将确保 CattleClass.find() 在运行 WeekCount.findOne() 之前完成执行

如果您需要更多信息,有很多关于 Stack Overflow 处理异步代码的精彩帖子。

【讨论】:

我已经能够使用虚拟数据进行保存,所以这就是问题所在。现在重写它。完成后将发布解决方案。感谢您的帮助,不胜感激。【参考方案2】:

下面的代码现在可以正常工作了。

使用 .then() 而不是混合回调和承诺。 感谢您的帮助!

exports.weekCount_create_post = [
  validator
    .body("dateOfCount", "Week Count Data Required")
    .toDate()
    .isLength( min: 1 )
    .trim(),

  // Sanitize (escape) the name field.
  validator.sanitizeBody("*").escape(),

  // Process request after validation and sanitization.
  (req, res, next) => 
    var weekCountDetail = 
      dateOfCount: req.body.dateOfCount
    ;

    const errors = validator.validationResult(req);

    if (!errors.isEmpty()) 
      // There are errors. Render the form again with sanitized values/error messages.
      console.log("ERRORS!s");
      async.parallel(
        
          camps: function(callback) 
            Camp.find()
              .sort("name")
              .exec(callback);
          ,
          cattleClasses: function(callback) 
            CattleClass.find(callback);
          
        ,
        function(err, results) 
          if (err) 
            return next(err);
          
          res.render("weekCount_form", 
            title: "There were Errors! New Week Count",
            camps: results.camps,
            cattleClasses: results.cattleClasses
          );
        
      );

      return;
     else 
      Camp.find(, "name")
        .exec()
        .then(list_camps => 
          return CattleClass.find(, "name")
            .exec()
            .then(list_cattleClasses => 
              return [list_camps, list_cattleClasses];
            );
        )
        .then(qResult => 
          list_camps = qResult[0];
          list_cattleClasses = qResult[1];
          var campCountArray = [];

          list_camps.forEach(function(campName) 
            var campCount = new CampCount(
              campName: campName.name
            );

            var emptyCount = true;
            list_cattleClasses.forEach(function(cattleClassName) 
              var tempVar = campName.name + "." + cattleClassName.name;
              var tempNum = parseInt(req.body[tempVar]);
              if (tempNum) 
                campCount.count[cattleClassName.name] = req.body[tempVar];
                emptyCount = false;
               else 
                campCount.count[cattleClassName.name] = 0;
              
            );

            if (!emptyCount) 
              campCount.save(function(err) 
                if (err) 
                  return next(err);
                
              );

              campCountArray.push(campCount);
            
          );

          weekCountDetail.campCounts = campCountArray;
          return weekCountDetail;
        )
        .then(weekCountDetail => 
          WeekCount.findOne( dateOfCount: req.body.dateOfCount )
            .exec()
            .then(found_weekCount => 
              if (found_weekCount) 
                res.redirect(found_weekCount.url);
               else 
                console.log("Not FOUND");
                var weekCount = new WeekCount(weekCountDetail);
                console.log("WEEKCOUNT3");
                console.log(weekCount);
                weekCount.save(err => 
                  if (err) 
                    return next(err);
                  
                  res.redirect(weekCount.url);
                );
              
            )

            .catch(err => 
              console.log("error findOne " + err);
              return next(err);
            );
        );
    
  
];

【讨论】:

以上是关于我正在学习 express 和 mongoose,我无法保存要保存的模式,但可以通过 console.log() 看到它的主要内容,如果未能解决你的问题,请参考以下文章

无法通过 express/mongoose/angularjs 从 Mongodb 访问数据

Express App 中的 Mongoose 模型(未被要求找到)

Express + Mongoose + 聚合 + 计算可用库存

使用 Nodejs、Express、Mongoose 和 React 将图像上传到 MongoDB

Express: POST 数据到数组 mongoose 和节点

Nodejs+Express学习二(Mongoose基础了解)