pjnovas
pjnovas

Reputation: 1116

Mongoose: Add new Schema property and update all current documents

I have at production a NodeJS application running using MongoDB and Mongoose, which inside has a Mongoose Schema like:

var Product = new Schema({
    "name": { type: String, required: true }
  , "description": { type: String }
});

Now, as a new requirement I'm adding a new property to the Schema at my local, like this:

var Product = new Schema({
    "name": { type: String, required: true }
  , "description": { type: String }
  , "isPublic": { type: Boolean, default: true }
});

When I restart my NodeJS process, I was expecting an update to all of my current documents (products), so now every document have a property isPublic which value is true.

What happened is no document has that new property and if I do a someProduct.Save({ isPublic: true }) it gets added.

Question: is there a way to accomplish that?, I know I can do a $set from command line with mongo client, but I want to know if there is a way where Mongoose will add the missing property after the Schema changed on a process restart.

Upvotes: 9

Views: 5335

Answers (2)

Quan Truong
Quan Truong

Reputation: 327

Your best bet is to use MongoSH. Adding a new property to a Mongoose Schema will never update existing documents unless the programmer does it.

Use the updateMany command in the Mongo Shell (MongoSH):

// Get all documents in the collection, and set the field to a value
db.users.updateMany( {} , 
    { $set: {"newlyCreatedField": "defaultValue"} }
);

Upvotes: 0

Rodrigo Medeiros
Rodrigo Medeiros

Reputation: 7862

What happened is no document has that new property and if I do a someProduct.Save({ isPublic: true }) it gets added.

That's because the mongoose default attribute works just for new documents. There're two workarounds:

  • Write your code to treat documents without the isPublic property as true;
  • Or, as you've mentioned above, set the property manually through mongodb console.

Upvotes: 6

Related Questions