can anyone help me for how can run mongoose query in forEach loop in nodejs and suggest for inner join result need of both collections
like below details
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}}));
})
                A nice elegant solution is to use the cursor.eachAsync() function. Credit to https://thecodebarbarian.com/getting-started-with-async-iterators-in-node-js.
The eachAsync() function executes a (potentially async) function for each document that the cursor returns. If that function returns a promise, it will wait for that promise to resolve before getting the next document. This is the easiest way to exhaust a cursor in 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);
  });
                        Schema.find() is an async function. So your last line of code will execute while you wait for the first job search is executed in your loop. I suggest change it to Promises and use Promise.all(array).
To do so, first you have to change to use Promise with mongoose. you can do this with bluebird like this:
var mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
Then you can use Promises instead of callbacks like this:
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);
});
EDIT How to list both jobs and users
If you want to have a structure like:
[{ 
  user: { /* user object */,
  jobs: [ /* jobs */ ]
}]
you could merge the lists together. listOfJobs is in the same order as the jobQueries list, so they are in the same order as the users. Save users to a shared scope to get access to the list in the 'then function' and then merge.
..
}).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);
});
                        No need to use forEach() which is synchronous and being called in an asynchronous fashion, that will give you wrong results.
You can use the aggregation framework and use $lookup which performs a left outer join to another collection in the same database to filter in documents from the "joined" collection for processing.
So the same query can be done using a single aggregation pipeline as:
userSchema.aggregate([
    {
        "$lookup": {
            "from": "jobs", /* underlying collection for jobSchema */
            "localField": "sno",
            "foreignField": "u_sno",
            "as": "jobs"
        }
    }
]).exec(function(err, docs){
    if (err) throw err;
    res.send(
        JSON.stringify({
            status: "success",
            message: "successfully done",
            data: docs
        })
    );
})
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With