首页 > 解决方案 > 使用猫鼬循环从两个集合中获取数据

问题描述

我想做搜索api。从请求正文位置搜索用户。为此,我需要来自两个集合的数据,即用户集合和 sessionSlot 集合。从用户集合想要全名、profilepic、位置、邮件等,从用户的 _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 集合中得到正确的响应,有时它被覆盖数据或有时为空(比如从数组中获取最后一个值)。

请给我建议!!

我正在使用 mongoose 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 }
    }]
})

标签: node.jsmongodbexpressmongoose

解决方案


根据您的代码,问题似乎出在您尝试加载 sessionSlots 的方式上,因此一旦您获得所有用户,您将使用简单的 for 循环(同步代码)来加载每个用户的 sessionSlots(这是异步的)所以也许尝试在那里使用 async each

像这样的东西

    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
            });
        });
    });
}

推荐阅读