13

Currently trailing out Mongoose and MongoDB for a project of mine but come across a segment where the API is not clear.

I have a Model which contains several keys and documents, and one of those keys os called watchList. This is an array of ID's that the user is watching, But I need to be sure that these values stay unique.

Here is some sample code:

var MyObject = new Mongoose.Schema({
    //....
    watching : {type: Array, required: false},
    //....
});

So my question is how can I make sure that the values pushed into the array only ever store one, so making the values unique, can i just use unique: true ?

Thanks

4 Answers 4

15

To my knowledge, the only way to do this in mongoose is to call the underlying Mongo operator (mentioned by danmactough). In mongoose, that'd look like:

var idToUpdate, theIdToAdd; /* set elsewhere */
Model.update({ _id: idToUpdate }, 
             { $addToSet: { theModelsArray: theIdToAdd } }, 
             function(err) { /*...*/ }
);

Note: this functionality requires mongoose version >= 2.2.2

Sign up to request clarification or add additional context in comments.

4 Comments

can theIdToAdd be an array, such as ["ID1", "ID2"] ?
I guess u could use $each for that.
@RoberPitt excellent point... theIdToAdd cannot be an array. If you do that, the item to be inserted will be that array. I'm trying to find a way to solve this :-(
7

Take a look at the Mongo documentation on the $addToSet operator.

1 Comment

So, $addToSet will add a new element into the array if it already doesn't contain a duplicate. Is there a way (e.g. creating a unique index), which will ensure there never are duplicated in an array? Basically, I want a Set instead of a Sequence.
1

Mongoose is an object model for mongodb, so one option is to treat the document as a normal javascript object.

MyModel.exec(function (err, model) {
   if(model.watching.indexOf(watchId) !== -1) model.watching.push(watchId);

   model.save(...callback);
});

Although, I do agree that mongoose should have some support for this built in the form of a validator for the collection document reference feature-- especially because most of the time you want to add only unique references.

1 Comment

This won't work if the set was added to the model by a concurrent operation, and in your example, you will be checking if the set exists in a stale copy of the model. Hence needing an enforced database level unique index.
0

That's how you can do it using Mongoose,

IF your upcoming value is an Array

Model
    .findOneAndUpdate({ _id: yourID }, 
    { $addToSet: { watching: { $each: yourWatchingArr } } },
    function(err) { /*...*/ }
    );

IF your upcoming value is a string

Model
    .findOneAndUpdate({ _id: yourID }, 
    { $addToSet: { watching: yourStringValue } },
    function(err) { /*...*/ }
    );

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.