Mongoose findOne内循环

时间:2017-06-12 12:19:39

标签: javascript node.js mongodb mongoose

我有一个document Usersstorage属性被定义为ObjectId的数组,引用了名为document的其他Storage。我正在尝试获取特定用户,然后在数组中返回存储信息。

这是我的代码:

module.exports.storageDetail = function(req, res) {
      User.findOne({'userId': req.user.userId}, 'storages').then(function(data){
        var storageArray = [];

        data.storages.forEach(function(record){
          Storage.findOne({_id: record}, function(err, storage){
            storageArray.push(storage);
          });
        });

        return Promise.all(storageArray);
      }).then(function(storageList){
        res.render('storage_template', {
          storage: storageList
        });
        console.log(storageList);
      });
}

但执行后,storageList是一个空数组。

我是node.js的新手,如果我需要提供更多信息,请告诉我。

3 个答案:

答案 0 :(得分:1)

所以这里的要点是你需要.exec()才能返回Promise。这就是你尝试失败的原因。但是语法上也有更好的方法。

而是使用.map()并致电.exec()以返回承诺

User.findOne({'userId': req.user.userId}, 'storages').then(function(data){
  var storageArray = data.storages.map(function(id) { 
    return Storage.findOne({_id: id }).exec() 
  });
  return Promise.all(storageArray);
}).then(function(storageList){
  res.render('storage_template', {
    storage: storageList
  });
  console.log(storageList);
});

或者使用$in.find(),其中方法返回一个数组,操作符允许您指定要匹配的数组:

User.findOne({'userId': req.user.userId}, 'storages').then(function(data){
  return Storage.find({ "_id": { "$in": data.storages } }).exec();
}).then(function(storageList){
  res.render('storage_template', {
    storage: storageList
  });
  console.log(storageList);
});

基本上看起来你可以简单地使用.populate()

User.findOne({'userId': req.user.userId}, 'storages')
  .populate('storages')
  .then(function(data) {
    res.render('storage_template', {
      storage: data.storages
    });
    console.log(data.storages);
  });

但是你的问题并不清楚这些是否真的被定义为对Storage模型的引用。

另请参阅mongoose文档中的Queries are not Promises

答案 1 :(得分:1)

如果您使用的是猫鼬,则可以使用.populate()storages收集中获取Storage个详细信息。

可以尝试这个

module.exports.storageDetail = function(req, res) {
  User.findOne({'userId': req.user.userId}, 'storages')
    .populate('storages')
    .exec(function (err, storageList) {
      if (err) return handleError(err);
      console.log(storageList);
      res.render('storage_template', {
        storage: storageList
      });
    });
}

要使用此.populate(),请先在User模型中首先确认ref已提交storages

像:

storages: [{ type: Schema.Types.ObjectId, ref: 'Storage' }]

答案 2 :(得分:0)

//执行npm install lodash

<select name="keys" ng-options="key as key.name for key in list track by key.id" ng-change="myCtrl()" ng-model="testValue"  class="select-input" style="margin-left:0px;">
</select>
相关问题