0

I have two collections in mongoose db. I have to find all the documents in a collection. After that, i have to iterate all the documents to find the corresponding document in second collection. For that, i was thinking to use for loop. But, since it is blocking in nature. How can I perform my task.

const docs = await collection1.find({name:"asdf"})
for(let i=0;i<docs.length;i++){
    const doc2 = await collection2.findOne({address:docs.address})
}
1
  • It's not blocking at all! While the db is retrieving results inside the loop (await collection2.findOne(...)), the main thread is taking care of "other things". Async/await does not block the event loop, in simple words await is just sugar-coating the nesting of promises and callbacks so that your code structure looks "flat". Something like reading a file with fs.readFileSync() inside the loop (or anywhere in your code) would block the event loop, but that's not the case with await. Commented Oct 20, 2020 at 9:31

1 Answer 1

2

I'm not sure if I really understand your problem, but if I do, I think you can push all yours promises inside an array, instead of using await. After that you can use the function Promise.all to await in on place for all promises inside the array. You can find below an example with your code:

const docs = await collection1.find({name:"asdf"})
const docs2 = [];
for(let i=0;i<docs.length;i++){
    docs2.push(collection2.findOne({address:docs.address}));
}

Promise.all(docs2).then((values) => {
  // at this point all your documents are ready
  // and your for is not blocking
  console.log(values);
});

But you have to be carefull to not abuse of this, if you fill an array with a lot of promises, it can lead to performance/memory issues. Regards

Sign up to request clarification or add additional context in comments.

7 Comments

sorry, but i meant to ask is if I will use a for loop, then it will block the event loop. How can i avoid either using for loop or use it such that it does not block event loop
@anitashrivastava the for loop itself is "blocking", but it's fast. Just don't do anything blocking IN the loop (like shown in this answer) and you should be fine.
Sorry, I am new with node js, how can i push the found result to the corresponding doc array object's index ?
on my example, values, just after the 'then' it's an array. It contains all your docs
Now, before using this code, think about the fact that you'll be flooding your database with parallel queries (it could be thousands!) and that this code should probably run with a collection2.find() that returns all docs you need instead of individual findOne() calls which are much slower. Basically running findOne() inside any kind of loop, with or without promises, is a database client antipattern and a performance code smell.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.