多个mongo查询,然后返回响应

时间:2019-06-14 16:37:56

标签: javascript node.js mongodb asynchronous

我正在尝试获取数据库中的集合列表,然后返回这些集合中的每个文档以进行备份。到目前为止,有效负载仍然返回空白。您如何等待有效载荷填充后再发送?我的db.close()也会去哪里?

注意:我知道我可以正确获取数据,因为如果我使用console.log(data)而不是将其推送,则可以正常工作。

app.post('/admin/saveMongoDB',async(req,res)=>{
  let payload=[]
  MongoClient.connect(url,{ useNewUrlParser: true}, function (err, db){
    if (err) throw err;
    var dbo = db.db("probes");
    dbo.listCollections().toArray().then(ctx=>{
      ctx.forEach(probe=>{
       dbo.collection(probe.name).find().toArray().then(data=>{
         payload.push(data)
        }).catch(err=>{console.log(err)})
      })
      res.send(payload)
    })
  })
})```

2 个答案:

答案 0 :(得分:0)

您的payload实际上将是一个空数组,因为ctx.forEach是在res.send(payload)之后执行的

由于您正在使用Promise,因此可以重新编写代码以利用Promise.all

dbo.listCollections().toArray().then(ctx => {
  const colls = ctx.map(probe => dbo.collection(probe.name).find().toArray())
  const Promise.all(colls)
    .then(results => {
      // results is an array
      res.send(results)
      db.close();
    })
    .catch(err=>{console.log(err)})
})

要注意的一件事是Promise.all快速失败功能。如果任何诺言失败(您的数据库查询之一失败),那么then将不会被调用。但是既然您要进行备份,那么我假设这是可以接受的。

答案 1 :(得分:0)

app.post('/admin/saveMongoDB', async (req, res) => {
  let payload = []
  let i = 0
  MongoClient.connect(url, {
    useNewUrlParser: true
  }, function (err, db) {
    if (err) throw err;
    var dbo = db.db("Accuprobes");
    dbo.listCollections().toArray().then(ctx => {
      ctx.forEach(probe => {
        dbo.collection(probe.name).find().toArray().then(data => {
          i++
          payload.push({
            [probe.name]: data
          })
          if (i == ctx.length) {
            res.send(payload)
            fs.writeFile('./backups/accuprobeHistoricalData' + (new Date).getTime() + '.txt', JSON.stringify(payload), function (err) {
              if (err) {
                return console.log(err)
              }
              console.log('MongoDB Succesfully Saved')
            })
          }
        }).catch(err => {
          console.log(err)
        })
      })
    })
  })
})

我最终通过创建一个迭代器解决了我的问题,当它与探测量匹配时,我就发送了响应。