【问题标题】:Get data from two collections in loop using mongoose使用猫鼬循环从两个集合中获取数据
【发布时间】:2018-12-20 23:53:54
【问题描述】:

我想做搜索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.js mongodb express mongoose


    【解决方案1】:

    根据您的代码,问题似乎在于您尝试加载 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
                });
            });
        });
    }
    

    【讨论】:

    • 为什么 slotData 条件中没有 else 部分?在我目前的情况下,所有用户的条目都不在 sessionSlot 集合中。假设在 userDetail 中,我得到 3 个用户列表。在这 3 个用户中,只有两个在该 sessionSlot 集合中有条目。那么如何处理条目不在 sessionSlot 集合中的第三个用户呢?
    • 好的!!!我也从简单的 for 循环更改为异步和其他东西!!!现在它工作正常!非常感谢..我真的很感激。所以我可以让你的答案正确..
    猜你喜欢
    • 2016-12-12
    • 1970-01-01
    • 2020-08-14
    • 2020-03-28
    • 1970-01-01
    • 1970-01-01
    • 2020-01-20
    • 2020-01-11
    • 1970-01-01
    相关资源
    最近更新 更多