简体   繁体   English

在Mongodb中使用多个FindOne

[英]Using Multiple FindOne in Mongodb

I am trying to extend the amount of fields that our API is returning. 我正在尝试扩展我们的API返回的字段数量。 Right now the API is returning the student info by using find, as well as adding some information of the projects by getting the student info and using findOne to get the info about the project that the student is currently registered to. 现在,API正在通过使用find返回学生信息,并通过获取学生信息并使用findOne来获取有关该学生当前注册的项目的信息来添加项目的一些信息。

I am trying to add some information about the course by using the same logic that I used to get the project information. 我试图通过使用与获取项目信息相同的逻辑来添加有关课程的一些信息。

So I used the same findOne function that I was using for Projects and my logic is the following. 因此,我使用了与Projects相同的findOne函数,其逻辑如下。

I created a variable where I can save the courseID and then I will put the contents of that variable in the temp object that sending in a json file. 我创建了一个变量,可以保存courseID,然后将其内容放入发送json文件的temp对象中。

If I comment out the what I added, the code works perfectly and it returns all the students that I require. 如果我注释掉我添加的内容,该代码将完美运行,并返回我需要的所有学生。 However, when I make the additional findOne to get information about the course, it stops returning anything but "{}" 但是,当我使用附加的findOne来获取有关课程的信息时,它将停止返回除“ {}”以外的任何内容

I am going to put a comment on the lines of code that I added, to make it easier to find. 我将在添加的代码行中添加注释,以使其更易于查找。

Any sort of help will be highly appreciated! 任何帮助将不胜感激!

User.find({
    isEnrolled: true,
    course: {
      $ne: null
    }
  },
  'email pantherID firstName lastName project course',
  function(err, users) {
    console.log("err, users", err, users);
    if (err) {
      return res.send(err);
    } else if (users) {
      var userPromises = [];
      users.map(function(user) {
        userPromises.push(new Promise(function(resolve, reject) {

          ///////// Added Code  START///////
          var courseID;

          Course.findOne({
              fullName: user.course
            }, function(err, course) {
              console.log("err, course", err, course);
              if (err) {
                reject('')
              }

              courseID = course ? course._id : null


              //console.log(tempObj)
              resolve(tempObj)
            }),

            ///// ADDED CODE END //////

            Project.findOne({
              title: user.project
            }, function(err, proj) {
              console.log("err, proj", err, proj);
              if (err) {
                reject('')
              }
              //Course ID, Semester, Semester ID
              //map to custom object for MJ
              var tempObj = {
                email: user.email,
                id: user.pantherID,
                firstName: user.firstName,
                lastName: user.lastName,
                middle: null,
                valid: true,
                projectTitle: user.project,
                projectId: proj ? proj._id : null,
                course: user.course,
                courseId: courseID
              }

              //console.log(tempObj)
              resolve(tempObj)
            })
        }))
      })
      //async wait and set
      Promise.all(userPromises).then(function(results) {
        res.json(results)
      }).catch(function(err) {
        res.send(err)
      })
    }
  })

using promise could be bit tedious, try using async , this is how i would have done it. 使用Promise可能有点乏味,请尝试使用async ,这就是我会做的事情。

// Make sure User, Course & Project models are required. 

const async = require('async');

let getUsers = (cb) => {
    Users.find({
        isEnrolled: true,
        course: {
            $ne: null
        }
    }, 'email pantherID firstName lastName project course', (err, users) => {
        if (!err) {
            cb(null, users);
        } else {
            cb(err);    
        }
    });
};

let findCourse = (users, cb) => {
    async.each(users, (user, ecb) => {
        Project.findOne({title: user.project})
            .exec((err, project) => {
                if (!err) {
                    users[users.indexOf(user)].projectId = project._id;
                    ecb();     
                } else {
                    ecb(err);
                }
            });
    }, (err) => {
        if (!err) {
            cb(null, users);
        } else {
            cb(err);
        }
    });
};

let findProject = (users, cb) => {
    async.each(users, (user, ecb) => {
        Course.findOne({fullName: user.course})
            .exec((err, course) => {
                if (!err) {
                    users[users.indexOf(user)].courseId = course._id;
                    ecb();     
                } else {
                    ecb(err);
                }
            });
    }, (err) => {
        if (!err) {
            cb(null, users);
        } else {
            cb(err);
        }
    });
};

// This part of the code belongs at the route scope
async.waterfall([
    getUsers,
    findCourse,
    findProject
], (err, result) => {
    if (!err) {
        res.send(result);
    } else {
        return res.send(err);        
    }
});

Hope this gives better insight on how you could go about with multiple IO transactions on the same request. 希望这样可以更好地了解如何处理同一请求上的多个IO事务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM