That is probably not the best schema design for a number of reasons. You would be better served by this:
{
"_id" : ObjectId("5321985944aebf2ca6f2075f"),
"ratings" : [
{
id: "532192d344aebf2ca6f2075e", score: 0
},
{
id: "532199d144aebf2ca6f20760", score: 1
}
],
"email" : "joe@example.com",
"name" : "Joe Bloggs"
}
At least in that way you can match on the id
of the element of the array.
To your problem though. $addToSet is a nice convenience, but of course does not solve your issue. It still can be used, but if you want to add to a "score" like this then you would have to use (with the new model of course):
var count = db.collection.find({
"_id" : ObjectId("5321985944aebf2ca6f2075f"),
"ratings.id": "532192d344aebf2ca6f2075e"
}).count();
if ( count != 0 ) {
db.collection.update(
{
"_id" : ObjectId("5321985944aebf2ca6f2075f"),
"ratings.id": "532192d344aebf2ca6f2075e"
},
{
"$inc": { "ratings.$.score": 1 }
}
);
} else {
db.collection.update(
{
"_id" : ObjectId("5321985944aebf2ca6f2075f"),
"ratings.id": "532192d344aebf2ca6f2075e"
},
{
"$push": {
"id": newId,
"score": newScore
}
}
);
}
Or whatever equivalent in your implementation language.
So $addToSet becomes a bit redundant in your case, as you need to check to decide whether you $set or $inc as your case may be. More involved, but it's the only way to do it.