【问题标题】:Error pushing objects into another object in mongodb将对象推送到 mongodb 中的另一个对象时出错
【发布时间】:2018-07-27 17:07:50
【问题描述】:

req.body.courses 有多个我想添加到特定类别的课程 id,问题是当我的代码运行时,它会保存一门课程不止一次,有时是四到五次,具体取决于数量循环次数。

功能:

router.post('/categories/:cat_id/', function (req, res) {
    Categorie.findById(req.params.cat_id, function(err, categorie){
    if(err){
      console.log(err);
    } else {
      var courses = req.body.courses;
      courses.forEach(function (course){
          Course.findOne({  _id:  course }, function(err, foundCourse) {
              if(err){
                  console.log(err);
              } else {
                  categorie.courses.push(foundCourse._id);
                  categorie.save();
              }
          });
      });
    }
  });
  return res.redirect('/dash');
});

CategorieSchema:

var categorieSchema = mongoose.Schema({
   name: String,
   courses: [
        {
            type: mongoose.Schema.Types.ObjectId,
            ref: "Course"
        }    
    ]
});

这是一个尝试将 4 门课程添加到类别的示例:

{ "_id" : ObjectId("5a871964a6b4820ecf7abaa7"), "courses" : [ ObjectId("5a870a7374486e0b0d69f710"), ObjectId("5a870a7a74486e0b0d69f711"), ObjectId("5a870a6974486e0b0d69f70f"),   
 ObjectId("5a870a7374486e0b0d69f710"), ObjectId("5a870a7a74486e0b0d69f711"), ObjectId("5a870a6974486e0b0d69f70f"), 
 ObjectId("5a870a7374486e0b0d69f710"), ObjectId("5a870a7a74486e0b0d69f711"), ObjectId("5a870a6974486e0b0d69f70f") ], "name" : "test2", "__v" : 3 }

【问题讨论】:

    标签: javascript node.js mongodb mongoose


    【解决方案1】:

    Node.js 是异步的,它不会等待循环完全执行,并且每次在现有数组中添加 _id 时都会增加 2-3 次。

    在我没有测试过的时候试试这个。

    const findOne = (course) => {
        return new Promise((resolve, reject) => {
            Course.findOne({
                _id: course
            }, (err, foundCourse) => {
                if (err)
                    return reject(err);
                return resolve(foundCourse._id);
            });
        });
    }
    
    router.post('/categories/:cat_id/', function (req, res) {
        Categorie.findById(req.params.cat_id, function (err, categorie) {
            if (err) {
                console.log(err);
                res.status(400).json(err);
            } else {
                var courses = req.body.courses;
    
                Promise.all(courses.map((course) => {
                    return findOne(course);
                })).then((data) => {
                    // check if course id already there skip
                    data = data.filter((course) => {
                        return !categorie.courses.includes(course);
                    });
                    categorie.courses = categorie.courses.concat(data);
                    categorie.save();
                    return res.redirect('/dash');
                }).catch((err) => {
                    console.log(err);
                    res.status(400).json(err);
                });
            }
        });
    });
    

    【讨论】:

      【解决方案2】:

      另一种方法是使用$in 运算符和Course.find() 返回课程的第一个查询,然后使用Categorie.findByIdAndUpdate() 更新类别模型中的courses 数组:

      router.post('/categories/:cat_id/', function (req, res) {
          Course.find({ '_id': { '$in': req.body.courses }}).exec((err, courses) => {
              Categorie.findByIdAndUpdate(
                  req.params.cat_id, 
                  { '$addToSet': { 'courses': courses } },
                  { 'new': true },
                  (err, categorie) => {
                      if (err){
                          console.log(err);
                      } else {
                          return res.redirect('/dash');
                      }
                  }
              });    
          });
      });
      

      【讨论】:

        猜你喜欢
        • 2019-07-13
        • 2014-06-07
        • 1970-01-01
        • 2016-03-05
        • 1970-01-01
        • 2021-04-23
        • 2019-12-22
        • 2019-04-11
        • 1970-01-01
        相关资源
        最近更新 更多