【问题标题】:how to populate schemaref in mongoose using callbacks?如何使用回调在 mongoose 中填充 schemaref?
【发布时间】:2012-11-01 16:52:10
【问题描述】:

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

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 });
});

【问题讨论】:

    标签: node.js express mongoose


    【解决方案1】:

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

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

    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 });
      });
    });
    

    【讨论】:

    • 感谢所有的帮助,userMap 似乎是最理智的。
    猜你喜欢
    • 2020-06-21
    • 1970-01-01
    • 2015-08-07
    • 2017-12-13
    • 2014-11-02
    • 2019-07-28
    • 2019-01-14
    • 2018-03-10
    • 1970-01-01
    相关资源
    最近更新 更多