-2

Here's my requirement

Pass a array of id's to some function which will do the following

  1. Check if a document exists in Mongodb if YES skip to next id if No create a document with specified id

  2. If all id's of array exist in db return a message all id's exist if not return message created missing documents

Tried several ways to do it but nothing was successful as desired.

Problems I ran into, missing documents created but the message all id's exist returned first before creation completed.

Tried using async but dint help. tried using array length and count of found docs this returned undefined.

**I'm using mongo native client and there's absolutely no problem with mongo queries in this case. The problem is with Node.js . node executes all at once, before the previous step has finished and I understand node is not sequential. since looking for a document and creating it takes time the next steps are executed first and then after all DB process is completed. I'm looking for a solution that will go step by step in a sequence.

David
  • 15
  • 7
  • 3
    When asking a question about a problem caused by your code, you will get much better answers if you provide code people can use to reproduce the problem. See [How to create a Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). – georgeawg Nov 20 '18 at 21:36

2 Answers2

0

It's been a while since I've used MongoDB, but there was an upsert flag, if I recall. You could do an upsert with $set:{_id: id}, and that should create blank documents for you with those id's. Make sure to have a backup of the db, in case you forget to put the set, because otherwise it'll update all your old documents as well, and make them blank. There should be very little nodejs needed for this, because mongo has that functionality for you in their query language. As for the All id's exists bit, I'm sure the documentation for upsert contains some useful info:
https://docs.mongodb.com/manual/reference/method/Bulk.find.upsert/

Edit:
I dug deeper. Upsert might only work on single document updates. In this case, you should just foreach over your id's and run individual updates for each.
https://docs.mongodb.com/manual/reference/method/db.collection.update/#upsert-parameter

djak250
  • 9
  • 3
  • Sorry if I'm not clear with my question, there's absolutely no problem with mongo queries in this case. The problem is with Node.js . node executes all at once even before the previous step has finished it is not sequential. since looking for a document and creating it takes time the next steps are executed first and then after all DB process is completed. I'm looking for a solution that will go step by step in a sequence. – David Nov 20 '18 at 21:27
  • @David I think what you need is the `async` module. See https://caolan.github.io/async/docs.html and https://stackoverflow.com/questions/25705067/using-async-waterfall-in-node-js. Alternatively, you can chain promises or callbacks in node to do what you want. – kevinadi Nov 21 '18 at 00:29
0

If you need to output the array of created documents, the easest way will be to use find. But if you need just to a count of the new elements, and they has same structure, you can use a trick with update operator. That will looks like update({ id: { $nin: arrayOfId }}, { $set: newDoc }, { upsert: true }), where newDoc is a structure of the new doc, and arrayOfId is an array of you id (you can work with _id same way). This operation returns a count of new documents.

And if you try to make a request from angular before component created, use the preloader. And, after you get the result - show it to user. Hope this will help you.

Mikita Melnikau
  • 1,655
  • 2
  • 15
  • 30