如何在forEach循环中运行mongoose查询

lak*_*yap 6 mongoose mongodb node.js express

任何人都可以帮助我如何在nodejs中的forEach循环中运行mongoose查询并建议两个集合的内部联接结果需要

如下细节

userSchema.find({}, function(err, users) {
    if (err) throw err;
    users.forEach(function(u,i){
        var users = [];
        jobSchema.find({u_sno:s.u.sno}, function(err, j) {
            if (err) throw err;
            if (!u) {
                res.end(JSON.stringify({
                    status: 'failed:Auction not found.',
                    error_code: '404'
                }));
                console.log("User not found.");
                return 
            }
            users.push(j);
        })
    })
    res.send(JSON.stringify({status:"success",message:"successfully done",data:{jobs:j,users:u}}));
})
Run Code Online (Sandbox Code Playgroud)

R. *_*sen 12

Schema.find()是一个异步函数.因此,当您等待在循环中执行第一个作业搜索时,您的最后一行代码将会执行.我建议将其更改为Promises并使用Promise.all(array).

要做到这一点,首先你必须改为使用带有猫鼬的Promise.你可以用蓝鸟这样做:

var mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
Run Code Online (Sandbox Code Playgroud)

然后你可以使用Promises而不是像这样的回调:

userSchema.find({}).then(function(users) {
  var jobQueries = [];

  users.forEach(function(u) {
    jobQueries.push(jobSchema.find({u_sno:s.u.sno}));
  });

  return Promise.all(jobQueries );
}).then(function(listOfJobs) {
    res.send(listOfJobs);
}).catch(function(error) {
    res.status(500).send('one of the queries failed', error);
});
Run Code Online (Sandbox Code Playgroud)

编辑如何列出作业和用户

如果你想拥有一个像这样的结构:

[{ 
  user: { /* user object */,
  jobs: [ /* jobs */ ]
}]
Run Code Online (Sandbox Code Playgroud)

你可以将列表合并在一起.listOfJobs与jobQueries列表的顺序相同,因此它们与用户的顺序相同.将用户保存到共享范围以访问"then函数"中的列表,然后合并.

..
}).then(function(listOfJobs) {
  var results = [];

  for (var i = 0; i < listOfJobs.length; i++) {
    results.push({
      user: users[i],
      jobs: listOfJobs[i]
    });
  }

  res.send(results);
}).catch(function(error) {
  res.status(500).send('one of the queries failed', error);
});
Run Code Online (Sandbox Code Playgroud)


pen*_*ngz 6

一个优雅的解决方案是使用该cursor.eachAsync()函数。归功于https://thecodebarbarian.com/getting-started-with-async-iterators-in-node-js

eachAsync() 函数为游标返回的每个文档执行一个(可能是异步的)函数。如果该函数返回一个承诺,它将等待该承诺解决后再获取下一个文档。这是在 mongoose 中耗尽游标的最简单方法。

  // A cursor has a `.next()` function that returns a promise. The promise
  // will resolve to the next doc if there is one, or null if they are no
  // more results.
  const cursor = MyModel.find().sort({name: 1 }).cursor();

  let count = 0;
  console.log(new Date());
  await cursor.eachAsync(async function(doc) {
    // Wait 1 second before printing first doc, and 0.5 before printing 2nd
    await new Promise(resolve => setTimeout(() => resolve(), 1000 - 500 * (count++)));
    console.log(new Date(), doc);
  });
Run Code Online (Sandbox Code Playgroud)


tdo*_*dog 0

你可以使用这个:

db.collection.find(query).forEach(function(err, doc) {
   // ...
});
Run Code Online (Sandbox Code Playgroud)

  • 因为 foreach 是原生 mongodb 函数而不是 mongoose 函数 (6认同)
  • 我得到的错误是:**.forEach 不是函数**。为什么? (3认同)