Insert all or none based on condition

I have a custom requirement of inserting documents. Each document has an id, lets say. If any of the document ids already exist, I do not insert anything. If none of the ids exist, I insert all the documents.

Is there any way I can do this?

Upsert does not work here because upsert will insert or update. It doesn’t skip over. This will result in partial insert where some documents will get inserted which I do not want. It must be either all or none.

Hello @Sebin_Mathew, welcome to the forum.

This is one way to work with your situation, and it requires using a transaction.

let docs = [ { id: 10, fld1: "str-1" }, { id: 12, fld1: "str-200" } ]
let ids = [ 10, 12 ]

// Start transaction

let matches = db.collection.countDocuments({ id: { $in: ids } })

if (matches == 0) {

  print("There are zero matched ids in the collection. Inserting all ids!"

  let bulkInserts = []

  for (let doc of docs) {
     bulkInserts.push( { insertOne : { document: doc } } )
  }

  db.collection.bulkWrite( bulkInserts, { ordered : true } )
}
else {
  print("There are matched ids in the collection. Not inserting any!"
}

//  End transaction

NOTES:

bulkWrite() takes an array of write operations (in this case insertOne) and executes each of them. db.collection.bulkWrite() can be used inside multi-document transactions.

Also see Error Handling inside Transactions, which is important about how to handle the rollback if the bulk write operation fails with one of the inserts.

Note, the above code doesn’t include the error handling and code related to the transaction. To work with transactions, your deployment need to be replica-set with MongoDB v4.0 (or higher) or a sharded cluster with MongoDB v4.2.