node.js - 如何使用回调填充 Mongoose 中的schemaref?

标签 node.js express mongoose

我有一个从 mongoose 检索的项目列表,每个项目都引用了一个列表对象,但我需要以某种方式填充与每个列表关联的 item.list.user 对象,以便我可以在模板中将它们用作 item.list.user.username。

Item.find().populate('list').exec(function(err, items){
  items.forEach(function(item){
    User.findById(item.list.user), function(err, user){
      item.list.user = user;
    });
  });

 //how to get back here from User.findById() so I can render?
 res.render('index', { items: items });
});

最佳答案

有几种方法可以解决这个问题。主要问题是您假设渲染模板时将填充数据。情况并非总是如此,您可以而且应该始终假设,任何时候执行异步函数时,除非您等到每个函数调用完成,否则异步函数都不会完成。

这是一种确保数据可用于渲染的简单方法。

Item.find().populate('list').exec(function (err, items) {
  var len = items.length
    , populatedItems = [];
  items.forEach(function(item, i){
    User.findById(item.list.user, function (err, user) {
      item.list = item.list.toObject();
      item.list.user = user;
      populatedItems.push(item);
      if (i + 1 === len) {
        res.render('index', { items: items });
      }
    });
  });
});

尽管这不是很有效并且会进行不必要的数据库调用。我认为这也更难推理。

Item.find().populate('list').exec(function (err, items) {
  var itemMap = {}
  items.forEach(function (item, i) {
    // Map the position in the array to the user id
    if (!itemMap[item.list.user]) {
      itemMap[item.list.user] = [];
    }
    itemMap[item.list.user].push(i)
    item.list = item.list.toObject()
  });
  // Can pull an array of user ids from the itemMap object
  User.find({_id: {$in: Object.keys(itemMap)}}, function (err, users) {
    users.forEach(function (user) {
      itemMap[user._id].forEach(function(id) {
        // Assign the user object to the appropriate item
        items[id].list.user = user;
      })
    });
    res.render('index', { items: items });
  });
});

在 IRC 上与您进一步讨论并进行故障排除后,以下是针对您的特定案例的工作示例。

Item.find().populate('list').exec(function (err, items) {
  var itemIds = [];
  items.forEach(function (item) {
    itemIds.push(item.list.user)
  });
  // Can pull an array of user ids from the itemMap object
  User.find({_id: {$in: itemIds}}, function (err, users) {
    var userMap = {}
    users.forEach(function (user) {
      userMap[user._id] = user
    });
    res.render('index', { items: items, userMap: userMap });
  });
});

关于node.js - 如何使用回调填充 Mongoose 中的schemaref?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13172376/

相关文章:

javascript - 使用redux+react时表达忽略403错误

node.js - 由于空数组包含电子邮件为空的文档,MongoDB错误E11000重复键错误集合

windows - 如何在Windows中使用nodejs安装node-mongodb-native

apache - Socket.io 通过 apache 服务器聊天(也运行 php 主站点)

node.js - 使用返回 promise 的多个步骤对自定义查找器进行 Sequelize

node.js - Marklogic 8 Node.js API - 短语搜索

javascript - 将服务器端数据共享到 JS 文件

javascript - Node.js 和 SQL 检查数据库的结果

node.js - 关于express.cookieSession()的几个问题

node.js - 如何使用 mongoose 的 findOneAndUpdate 方法更新嵌入对象的某些字段而不丢失其他字段?