how can run mongoose query in forEach loop
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);
});
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);
});