title: Mongo duplicate key error on upsert or save
body: <p>I'm running into a problem inserting data into mongo via nodejs. I'm loading json objects into documents through either <code>upsert:true</code>, or <code>.save()</code> called on a returned mongoose document.</p>
  
  <p><strong>EDIT:</strong> I forgot to point out one important point, that this does work. I update 30-40,000 documents correctly. It will run for a while, then eventually throw this error. The "unique key (<code>xId</code>) is a different string each time, so I don't think it's caused by the data actually being loaded...</p>
  
  <p>Here's the schema:</p>
  
  <pre><code>var rosterSchema = new Schema({
  name        : String,
  xId     : {type:String, unique: true},
  event       : {type:ObjectId, ref:'Event'},
  team        : {type:ObjectId, ref:'Team'},
  division    : {type:ObjectId, ref:'Division'},
  place       : String,
  players     : [{type:ObjectId,ref:"Player"}],
  staff       : [{type:ObjectId,ref:"Player"}],
  matches     : [{type:ObjectId,ref:"Match"}],
  });
  </code></pre>
  
  <p>Error:</p>
  
  <pre><code>MongoError: E11000 duplicate key error collection: r_fix.rosters index: xId_1 dup key: { : "6RNoYBSsCAJRsjxs" }
      at Function.MongoError.create
  </code></pre>
  
  <p>Each run of the parse/load function targets a single roster page, which references other rosters in their matches.</p>
  
  <p>Most of the rosters already exist from loading other data.</p>
  
  <p>I can't guarantee the order that the rosters will be parsed, so I may need to create a 'match' against a roster that doesn't exist yet, which requires the new roster to be created, hence why I use <code>findOneAndUpdate</code> as opposed to <code>find</code></p>
  
  <p>Any idea what might be causing this? I'm trying to avoid pasting the whole source so these are each of the individual calls, with what I believe to be relevant info:</p>
  
  <pre><code>var rosterObj = {
      xId     : id,
      name    : rosterJson.team_name,
  };
  Roster.findOneAndUpdate({xId:rosterObj.xId},{$set:rosterObj},{new: true, upsert: true, setDefaultsOnInsert: true})
      .exec((err,roster)=&gt;{
          if(err)throw(err);
  
      }).then((roster)=&gt;{
  
      ...
  </code></pre>
  
  <p>The above roster returns the document used in all subsequent <code>save()</code>'s</p>
  
  <pre><code>roster.event = event._id;
  roster.save((err)=&gt;{if(err)throw(err)})
  </code></pre>
  
  <p>...</p>
  
  <pre><code>roster.team = team._id;
  roster.save((err)=&gt;{if(err)throw(err)})
  </code></pre>
  
  <p>...</p>
  
  <pre><code>if(pObj.staff == "No")
          roster.players.addToSet(player._id);
      else
          roster.staff.addToSet(player._id);
  
      roster.save((err)=&gt;{if(err)throw(err)});
  </code></pre>
  
  <p>...</p>
  
  <pre><code>if(!roster.event)
          if(oppRoster.event){
              roster.event = oppRoster.event;
              roster.save((err)=&gt;{if(err)throw(err)});
          }
  </code></pre>
  
  <p>...</p>
  
  <pre><code>var rosterObj = {
      xId:mObj.vs.roster_id, 
      event:roster.event,
  }    
  Roster.findOneAndUpdate({xId:rosterObj.xId},{$set:rosterObj},{new: true, upsert: true, setDefaultsOnInsert: true}).exec((err,oppRoster)=&gt;{
          if(err)throw(err);
  
          return oppRoster;
      })
  </code></pre>
  
  <p>As far as I understand it, when I use a single key for the find, and it's the only <code>unique:true</code> value in the document, then <code>doc.save()</code> and <code>doc.findOneAndUpdate({ ... , {upsert :true...})</code> should never return a duplicate key error.</p>
  
  <p>My <code>catch()</code> at the end of the promise chain doesn't catch these thrown errors either, but that is an entirely different problem.</p>
  
  <p>But I don't know anything, so that's why I'm here!</p>
  
  <p>EDIT: I should point out that I'm doing this over a large number of documents, but they're all promise-chained, so only one 'roster' should be getting updated at one time.</p>