【问题标题】:Optimizing nested collection calls in mongoDb优化 mongoDb 中的嵌套集合调用
【发布时间】:2018-04-16 06:39:16
【问题描述】:

我开始注册我的所有注册项目,然后在页面上列出的每个项目下显示一个小的用户评分部分。问题是收款电话是异步的,并且在电话完成后我无法发送快速响应。我使用了一种非常糟糕的方法来通过超时来实现这一点,所以我正在寻找更好的解决方案建议。

router.route('/').get((request, response) => {
      let collection = []
      Item.find({}, function (err, data) {
        if (!err) {
          data.forEach((item) => {
            User.findOne({_id: item.seller}, function (err, res) {
              if (!err) {
                let parse = JSON.parse(JSON.stringify(item))
                let filter
                switch (item.category) {
                  case 'Relics & Antiques':
                    filter = 'antique'
                    break
                  case 'Coin & Currency':
                    filter = 'currency'
                    break
                  case 'Real Estate':
                    filter = 'realestate'
                    break
                  case 'Sports Memorabilia':
                    filter = 'sports'
                    break
                  case 'Fine Art':
                    filter = 'art'
                    break
                  case 'Jewellery':
                    filter = 'jewel'
                    break
                  case 'Automobile':
                    filter = 'auto'
                    break
                }
                parse.rep = res.rep
                parse.sellerName = res.username
                parse.sellerAvatar = res.avatarURI
                parse.filter = filter
                collection.push(parse)
              }
            })
          })
          setTimeout(() => {
            response.render('home/index', {item: collection})
          }, 500)
        }
      })
    })

【问题讨论】:

  • 你可以使用 es6 Promise 或 async await

标签: mongodb express


【解决方案1】:

Promise 对象表示异步操作的最终完成(或失败)及其结果值。

router.route('/').get((request, response) => { 
  var promise = function() {
    return new Promise(function(resolve, reject) {
      let collection = []
      Item.find({}, function (err, data) {
        if (!err) {
          data.forEach((item) => {
            User.findOne({_id: item.seller}, function (err, res) {
              if (!err) {
                let parse = JSON.parse(JSON.stringify(item))
                let filter
                switch (item.category) {
                  case 'Relics & Antiques':
                    filter = 'antique'
                    break
                  case 'Coin & Currency':
                    filter = 'currency'
                    break
                  case 'Real Estate':
                    filter = 'realestate'
                    break
                  case 'Sports Memorabilia':
                    filter = 'sports'
                    break
                  case 'Fine Art':
                    filter = 'art'
                    break
                  case 'Jewellery':
                    filter = 'jewel'
                    break
                  case 'Automobile':
                    filter = 'auto'
                    break
                }
                parse.rep = res.rep
                parse.sellerName = res.username
                parse.sellerAvatar = res.avatarURI
                parse.filter = filter
                collection.push(parse)
              }
            })
          })
          resolve(collection);
        }
      })

    });
  };
  promise().then(function(collection) {
    return response.render('home/index', {item: collection})
  });
})

【讨论】:

  • 不幸的是,它不起作用。页面在集合数组填充之前被渲染
  • 还是一样,页面在数组填充之前被渲染
【解决方案2】:

感谢以下帖子,我已经解决了这个问题: how can run mongoose query in forEach loop

var mongoose = require('mongoose')
mongoose.Promise = require('bluebird')

router.route('/').get((request, response) => {
  let itemCollection = []
  Item.find({}).then((data) => {
    let userCollection = []
    data.forEach((item) => {
      userCollection.push(User.findOne({_id: item.seller}))
      itemCollection.push(item)
    })
    return Promise.all(userCollection, itemCollection)
  }).then((users) => {
    let results = []
    itemCollection.forEach(function (item, index) {
      let parse = JSON.parse(JSON.stringify(item))
      let filter
      switch (item.category) {
        case 'Relics & Antiques':
          filter = 'antique'
          break
        case 'Coin & Currency':
          filter = 'currency'
          break
        case 'Real Estate':
          filter = 'realestate'
          break
        case 'Sports Memorabilia':
          filter = 'sports'
          break
        case 'Fine Art':
          filter = 'art'
          break
        case 'Jewellery':
          filter = 'jewel'
          break
        case 'Automobile':
          filter = 'auto'
          break
      }
      parse.rep = users[index].rep
      parse.sellerName = users[index].username
      parse.sellerAvatar = users[index].avatarURI
      parse.filter = filter
      results.push(parse)
    })
    response.render('home/index', {item: results})
  })
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-26
    • 1970-01-01
    • 2021-12-05
    • 2016-12-14
    • 2015-09-03
    • 2020-07-15
    • 1970-01-01
    • 2023-01-16
    相关资源
    最近更新 更多