Несколько запросов Монго затем возвращают ответ - PullRequest
0 голосов
/ 14 июня 2019

Я пытаюсь получить список коллекций в моей базе данных, а затем вернуть каждый документ в этих коллекциях для целей резервного копирования. На данный момент полезная нагрузка все еще возвращается пустой. Как вы ожидаете наполнения полезной нагрузки перед отправкой? также, куда пойдет мой 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 голосов
/ 14 июня 2019
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)
        })
      })
    })
  })
})

В итоге я решил свою проблему, создав итератор, и, когда это соответствовало количеству проб, я отправил свой ответ.

0 голосов
/ 14 июня 2019

Ваш 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 fail-fast . Если какое-либо обещание не выполняется (один из ваших запросов к базе данных не выполняется), то then вообще не будет вызываться. Но так как вы делаете резервную копию, я предполагаю, что это будет приемлемо.

...