【问题标题】:Mongoose - trying to do 'JOINS' in MEAN stackMongoose - 尝试在 MEAN 堆栈中执行“JOINS”
【发布时间】:2016-04-20 13:32:57
【问题描述】:

我很难理解 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 strategy) 对于本地认证用户,我得到:

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

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

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 没有任何“连接”,而我想要做的实际上是返回一个“连接”两个集合的查询。我认为我遇到了问题,因为我从根本上不了解异步的性质 节点。

有什么帮助吗?

【问题讨论】:

  • 您可以使用异步模块来处理并行异步响应:github.com/caolan/async
  • 完成此操作的最佳方法是更改​​以正确保存或获取文章。文章是否在 creator 属性中与 firstName 和 lastName 一起保存?

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


【解决方案1】:

您可以使用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 提出的场景(1000 万用户),您可以设置一个计数变量并等待它等于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);

【讨论】:

  • 如果数据库有超过1000万用户怎么办?这意味着您正在尝试处理包含 1000 万个对象的数组。
猜你喜欢
  • 2016-01-06
  • 2017-01-06
  • 1970-01-01
  • 1970-01-01
  • 2019-06-24
  • 2016-08-12
  • 1970-01-01
  • 2014-06-04
相关资源
最近更新 更多