0

I have a cluster of node worker servers that handle hitting an api and inserting data into a mongo db. The problem I am having is that one of these functions appears to every so often insert two copies of the same document. It checks if the document has already been created with a query like so:

gameDetails.findOne({ gameId: gameId }, function(err, gameCheck) {

            if (!gameCheck) { //insert the document };

How can I ensure that this function always is only running one instance at a time. Alternatively, if I have not deduced the actual root problem, what could cause a mongo query like this to sometimes result in multiple of the same document, containing the same gameId, to be inserting?

TDmoneybanks
  • 478
  • 1
  • 7
  • 20

1 Answers1

0

findOne is being called multiple times before the document has had time to be inserted, i.e. something like the following is happening:

findThenInsert() findThenInsert() findThenInsert() // findOne returns null, insert called // findOne returns null, insert called // document gets inserted // findOne returns a gameCheck // document gets inserted

You should use a unique index to prevent duplicates. Then, your node instances could optimistically call insert straight away, and simply handle the error if they were too late, which is similar to your 'if found do nothing' logic.

Alternatively if you don't mind the document being updated each time, you can use the upsert method, which is atomic:

db.collection.update(query, update, {upsert: true})

Also see

MongoDB atomic "findOrCreate": findOne, insert if nonexistent, but do not update

Community
  • 1
  • 1
alzclarke
  • 1,725
  • 2
  • 17
  • 20