使用猫鼬从循环中的两个集合中获取数据

时间:2018-07-12 16:52:36

标签: node.js mongodb express mongoose

我想制作搜索API。从请求正文位置搜索用户。为此,我需要来自两个集合的数据,即用户集合和sessionSlot集合。从用户集合中获取全名,个人档案图片,位置,邮件等,并从用户的_id中获取来自sessionSlot集合的数据。

我尝试了以下代码:

var register = mongoose.model("user");
var sessionSlot = mongoose.model("sessionSlot");

register.find({
          'location.address': {
            $regex: '^' + req.body.address,
            $options: 'i'
          },
        }]
      }).exec(function (err, userDetail) {
        for (var i = 0; i < userDetail.length; i++) {

          sessionSlot.findOne({
            'userID': userDetail[i]._id
          }).exec(function (err1, slotData) {
            if(slotData) {
              if(slotData.sessions.length > 0) {
                async.eachSeries(slotData.sessions, (slots, callback) => {
                  if (req.body.date) {
                    if (moment(slots.date).isSame(moment(req.body.date), 'day')) {
                      // console.log('slots--->', slots);                  
                      sessionData.push({
                        time: slots.time,
                        status: slots.status,
                        slotID: slotData.slotID,
                      });
                    }
                  }
                  else {
                    sessionData.push({
                      time: slots.time,
                      status: slots.status,
                      slotID: slotData.slotID,
                    });
                  }
                  slotCnt++;
                  callback();
                });
              }
            }
            else {
              console.log('no slot created..',slotData);
              sessionData = [];
            }
           })
        }
        res.json({'code':200, 'data':sessionData})
      })

我没有从sessionSlot集合中获得正确的响应,有时它是被覆盖的数据,有时是null(例如从数组中获取最后一个值)。

请给我建议!

我正在使用猫鼬版本4.5(未使用聚合)

user schema: 
var UserSchema = mongoose.Schema({ 
   fullname:   { type: String, default: null },
   mail :   { type: String, default: null },
   profilepic :   { type: String, default: null },
})

sessionSlot schema:
var sessionSlotSchema = mongoose.Schema({

    userID      : { type: String },
    mail        : { type: String },
    slotID      : { type: String },
    slotFlag    : { type: Boolean },
    sessions    : [{
                    status       : { type: String, default:'empty' },
                    profilepic   : { type: String, default:null },
                    fullname     : { type: String, default:null },
                    autoBook     : { type: Boolean, default:false },
                    time         : { type: String, default: null }
    }]
})

1 个答案:

答案 0 :(得分:0)

根据您的代码,问题似乎在于您尝试加载sessionSlots的方式,因此一旦获得所有用户,您就使用简单的for循环(同步代码)加载每个用户的sessionSlots(异步)所以也许尝试在每个地方使用异步

也许是这样

    let sessionData = [];

    register.find({
        'location.address': {
          $regex: '^' + req.body.address,
          $options: 'i'
        },
    //   }] typo
    }).exec(function (err, userDetail) {
        if (err) {
            // send error response
            return;
        }

        if (!userDetail || !userDetail.length) {
           // send empty response ?
           return res.json({
               code: 200,
               data: []
           });
       }

        async.eachSeries(userDetail, (user, callback) => {
            sessionSlot.findOne({
                'userID': user._id
            }).exec(function (err1, slotData) {

                if(slotData && slotData.sessions.length) {
                    slotData.sessions.forEach((slots) => {
                        if (req.body.date) {
                          if (moment(slots.date).isSame(moment(req.body.date), 'day')) {
                            sessionData.push({
                              time: slots.time,
                              status: slots.status,
                              slotID: slotData.slotID,
                            });
                          }
                        }
                        else {
                          sessionData.push({
                            time: slots.time,
                            status: slots.status,
                            slotID: slotData.slotID,
                          });
                        }

                        // slot count will get incremented no matter what happens, is that okay ?
                        slotCnt++;
                    });
                }
                else {
                        // DONT DO THIS because the sessionData is collection of results of all users so 
                        // we shouldn't be clearing that collection if one user fails to meet certain condition
                        // unless it is your requirement

                        // console.log('no slot created..',slotData);
                        // sessionData = [];
                }

                callback();
            });
        }, (err) => {
            if (err) {
                //send error
                return;
            }

            res.json({
                code: 200,
                data: sessionData
            });
        });
    });
}