4

I'm trying do an upsert using Mongoose, but I'm getting a duplicate key error for the very key that should trigger the upsert.

Schema:

"resource": {type: Schema.ObjectId, ref: "Resource"},                       
"skill": {type: Schema.ObjectId, ref: "Skill"},                             
"level": {type: Number, min: 1, max: 5}

.index({skill: 1, resource: 1}, {unique: true});

Then I make the call:

    //self is a Resource instance
    ResourceSkillLevel.update({                                           
        resource: self._id,
        skill: skill._id,
        level: level
    }, {$set: {level: level}}, {upsert: true}, cb);

If the (resource, skill) does not exist, this call works just fine and properly creates the ResourceSkillLevel entry. However, when I call it again I get duplicate key error index. The listed duplicate key is the tuple resource/skill key. Why isn't it upserting when it finds the duplicate?

Explosion Pills
  • 188,624
  • 52
  • 326
  • 405

1 Answers1

7

You're including level in the update query criteria parameter, so if that doesn't also match the existing record it will try and create a new doc which will fail the unique index which only spans skill and resource.

Try changing your update to this:

ResourceSkillLevel.update({                                           
    resource: self._id,
    skill: skill._id
}, {$set: {level: level}}, {upsert: true}, cb);
JohnnyHK
  • 305,182
  • 66
  • 621
  • 471