48

I need to push multiple values into an array in mongoose using one call. I tried doing it using a smaller array but the array is getting inserted as a sub-array.

var kittySchema = new mongoose.Schema({
        name: String,
        values: [Number]
});

var Kitten = db.model('Kitten', kittySchema);
Kitten.update({name: 'fluffy'},{$push: {values:[2,3]}},{upsert:true},function(err){
        if(err){
                console.log(err);
        }else{
                console.log("Successfully added");
        }
});

The result of the calling the above code thrice gives the below result:

{ "_id" : ObjectId("502b0e807809d79e84403606"), "name" : "fluffy", "values" : [ [ 2, 3 ], [ 2, 3 ], [ 2, 3 ] ] }

Whereas what I want is something like this:

{ "_id" : ObjectId("502b0e807809d79e84403606"), "name" : "fluffy", "values" : [ 2, 3 ,2 ,3, 2, 3] }

Another thing I noticed was that the type in the array (values) is specified as Number, then wouldnt the 'strict' option ensure that anything other than Numbers are not inserted ? In this case another array is being allowed to be inserted.

4 Answers 4

47

(Dec-2014 update) Since MongoDB2.4 you should use:

Kitten.update({name: 'fluffy'}, {$push: {values: {$each: [2,3]}}}, {upsert:true}, function(err){
        if(err){
                console.log(err);
        }else{
                console.log("Successfully added");
        }
});
Sign up to request clarification or add additional context in comments.

1 Comment

If no doc with {name: "fluffy"} in it exists, does {upsert: true} create it?; also, if I do {upsert: true, new: true}, can I do function(err, result) {} and get in result all of the documents that were created/updated?
41

Deprecated see other solution below using $push $each

Your example is close, but you want $pushAll rather than $push to have each value added separately (rather than pushing another array onto the values array):

var Kitten = db.model('Kitten', kittySchema);
Kitten.update({name: 'fluffy'},{$pushAll: {values:[2,3]}},{upsert:true},function(err){
        if(err){
                console.log(err);
        }else{
                console.log("Successfully added");
        }
});

4 Comments

NB: you may also want to look at $addToSet, which can be used to only add values to an array if they aren't there already.
Thanks Stennie! That works. I missed this part in the documentation.
@Stennie this only works for individual elements, not for concatenating arrays.
@Tom concatenating arrays can be done with $addToSet together with $each.
5

Or use the $each modifier with $addToSet:

https://docs.mongodb.com/manual/reference/operator/update/addToSet/#each-modifier

// Existing tags array
{ _id: 2, item: "cable", tags: [ "electronics", "supplies" ] }

// Add "camera" and "accessories" to it
db.inventory.update(
   { _id: 2 },
   { $addToSet: { tags: { $each: [ "camera", "accessories" ] } } }
 )

Comments

1

Currently, the updated doc doesn't support $pushAll. It seems to have been deprecated. Now the good choice is to use the combination of $push & $each

an example:

//User schema: {uid: String, transaction: [objects] }
const filter = {"uid": uid};
const update = {
        $push: {
            transactions: {$each: dataarr}
        }
    }
User.updateOne(filter, update, {upsert:true}, (err) => {
        if(err){
            console.log(err)
        }
    })

pass {upsert: true} at options to insert if the filter returns false.

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.