1

I'm trying to implement quite typical combination of $addToSet and $inc but for some strange reason $addToSet adds multiple records with the same id (works like $push):

{ _id: 52ce27691cb76b5a60cc11f7,
  news: 
   [ { _id: 52ce2769c2f35d3d21000018,
       count: 2,
       item: 52ce2769c2f35d3d21000017 },
     { item: 52ce2769c2f35d3d21000017,
       _id: 52ce2769c2f35d3d21000019 } ] }

Here is the code:

        this.update({ _id : interval._id },
            { $addToSet : { news : { item : item } } },
            function (err) {
                if (err) {
                    callback(err);
                    return;
                }

                this.update({ _id : interval._id, 'news.item' : item },
                    { $inc : { 'news.$.count' : 1 } },
                    callback);
            }.bind(this));

This code was called two times so two item: 52ce2769c2f35d3d21000017 was created. $inc part works well. item and interval are mongoose model objects.

Alex Netkachov
  • 13,172
  • 6
  • 53
  • 85

1 Answers1

2

From the documentation of $addToSet: "adds a value to an array only if the value is not in the array already"

But what is "the value"? In this case it's the entire object, because that's the value that you're trying to add to the array. However, the objects aren't equivalent because the one you've added first already has an increased count, while the to-be-added object does not. Hence, they don't have the same value in all fields and MongoDB doesn't regard them as being 'equal'.

Keep in mind that _id is not a special field in an embedded array and has no additional semantics.

mnemosyn
  • 45,391
  • 6
  • 76
  • 82
  • Thank you. Is there any method then that adds the value to the array by checking only one property? – Alex Netkachov Jan 09 '14 at 13:25
  • 2
    I'm not sure, but I don't think so. You can modify the query as suggested in http://stackoverflow.com/questions/14527980/can-you-specify-a-key-for-addtoset-in-mongo, but that calls for a multikey query and might even require a negation, which can be costly. I tend to not use embedded arrays for anything but the most simple operations. – mnemosyn Jan 09 '14 at 13:49