How to insert documents if they don’t already exist from within a remote method in MongoDb using LoopBack

Tags: , ,



I’m very new to MongoDB (about 4 days in) and I’m trying to insert documents into my collection from within a remote method using Loopback without adding duplicate documents.

I firstly tested adding documents as such:

Events.create(resultData);

Which worked without issue.

I then moved on to trying to add a document without adding duplicates a few other answers:

Events.update(data,data,{upsert: true});

However, this did not add anything to the database.

I decided to move on and try and see if I could first check to see if a document could be found from a collection and therefore not add the document. Similar to this answer.

if(Events.find({itemOfData: resultData.itemOfData},{limit: 1}).size < 1){
    Events.create(resultData);
}

However, as before it doens’t create any documents.

I’m not sure what to try next or whether my implementation of the above solutions is faulty.

Answer

Events.update(data,data,{upsert: true});

LoopBack models don’t expose MongoDB API. Methods like create are providing database-agnostic API that’s mapped by connectors to database commands.

If you want to insert a document only if it does not exist, you can use one of the following methods (depending on what you are trying to achieve):

  • replaceOrCreate
  • patchOrCreate (also known as upsert and updateOrCreate)
  • findOrCreate
  • upsertWithWhere

if(Events.find({itemOfData: resultData.itemOfData},{limit: 1}).size < 1){

The find method accepts a Filter object (see Querying data) which contains not only the condition for matching records, but also things like pagination and what related models to include. The condition is stored in where property of the Filter object.

Also the find method returns a Promise, you need to wait until it’s resolved before counting the number of returned records.

const found = Events.find({
  where: {itemOfData: resultData.itemOfData}
  limit: 1
});
if (found.size < 1){
  // ...
}

While the solution based on find may seem to work well in development, it introduces a race condition where two “same” records can be created when the application is under high load. Whenever possible, it’s advised to use built-in functions like patchOrCreate that use database-specific means to guarantee atomicity.



Source: stackoverflow