将对象推入mongodb中的另一个对象时出错

时间:2018-02-16 18:18:02

标签: javascript node.js mongodb mongoose

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 }

2 个答案:

答案 0 :(得分: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);
            });
        }
    });
});

答案 1 :(得分:0)

另一种方法是让第一个查询使用from functions.Tic_Tac_Toe import *运算符返回课程c:,然后使用$in更新Categorie模型中的Course.find()数组:

courses