猫鼬 - 试图做' JOINS'在MEAN堆栈中

时间:2016-01-15 01:27:03

标签: node.js mongodb mongoose mean-stack populate

我很难理解NodeJS的异步性质。

所以,我有一个这个架构的文章对象:

var ArticleSchema = new Schema({
  created: {
      type: Date,
      default: Date.now
  },
  title: {
      type: String,
      default: '',
      trim: true,
      required: 'Title cannot be blank'
  },
  content: {
      type: String,
      default: '',
      trim: true
  },
  creator: {
      type: Schema.ObjectId,
      ref: 'User'
  }
});

,用户架构是:

var UserSchema = new Schema({
firstName: String,
lastName: String,
...
});

问题是当我查询所有文档时:

exports.list = function(req, res) {
// Use the model 'find' method to get a list of articles
Article.find().sort('-created').populate('creator', 'firstName lastName fullName').exec(function(err, articles) {
    if (err) {
        // If an error occurs send the error message
        return res.status(400).send({
            message: getErrorMessage(err)
        });
    } else {
        // Send a JSON representation of the article 
        res.json(articles);
    }
});
};

我成功恢复了所有文章,但由于某些原因,文章创建者返回了不同的结果 对于本地认证用户(localStrategy)和facebook认证用户(facebook策略),对于本地认证的用户,我得到:

articles = {
creator: {
    id: 123,
    firstName: 'Jason',
    lastName: 'Dinh'
},
...
}

对于经过身份验证的用户,我得到:

articles = {
creator: {
    id: 123
},
...
}

我似乎无法掌握PassportJS API,所以我想要做的就是 迭代文章和每篇文章,使用文章创建者ID查找用户文档,并将用户firstName和lastName添加到文章对象:

for each article in articles {

User.findOne({ '_id': articles[i].creator._id }, function(err, person){

    //add user firstName and lastName to article        

});

}

res.json(articles);

你可能已经在这里看到了问题...我的循环在文件返回之前完成。

现在,我知道MongoDB没有任何加入'而我想要做的实际上是返回一个加入'两个系列。我想我遇到了问题,因为我从根本上不了解它的异步性质 节点

任何帮助?

1 个答案:

答案 0 :(得分:0)

您可以使用find代替findOne并在回调函数内迭代。

User.find({ }, function(err, personList){
    for each person in personList { 
      for each article in articles {
        if (person._id === article.creator._id) {
          //add user firstName and lastName to article
        }        
      }
    }
    res.json(articles);
});

<强>更新

考虑到@ roco-ctz建议的场景(10M用户),您可以设置一个计数变量并等待它等于articles.length

var count = 0;
for each article in articles {
  User.findOne({ '_id': articles[i].creator._id }, function(err, person){
    //add user firstName and lastName to article        
    count += 1;         
  });
}
while (count < articles.length) {
  continue;
}

res.json(articles);