sami_analyst
sami_analyst

Reputation: 1839

mongoose updating Subdocument's properties with $set not working

I want to update some properties of a Sub-Document. My Models and update function are looking like the following:

    const ParentSchema = mongoose.Schema({
      ...
      subs : [SubSchema],
      ...
    })
    const SubSchema = mongoose.Schema({
      ...
      name : String,
      price : Number,
      ...
    })

    const ParentModel = mongoose.model('Item', ItemSchema);

    function updateSubDocument(parentId, subId, updateObj){
      return ParentModel.update(
        {'_id' : parentId, 'subs._id' : subId},
        {
          '$set' : {
            'subs.$' : updateObj
          }
        },
        {
          new : false,
          overwrite : true,
          runValidators: true
        }
      ).exec();
    }

Now when I'm trying to update some properties of specific Sub-Documents, mongoose does 2 strange things:

  1. The properties of the Sub-Document are getting overwritten by the updateObj, so all other properties (which are not in the updateObj) are missing.

  2. I cant update the overwritten Sub-Document after the first a second time, the values are not changing

ubuntu : 16.04, mongoose : 5.1.3, nodejs : 8.11.1,

Upvotes: 1

Views: 1174

Answers (1)

Harekam Singh
Harekam Singh

Reputation: 66

  1. 'subs.$' : updateObj The culprit is this line, refer the doc for details

https://docs.mongodb.com/manual/reference/operator/update/positional/

Try Updating with the following query:

function updateSubDocument(parentId, subId, updateObj){
  return ParentModel.update(
    {'_id' : parentId, 'subs' : {$elemMatch:{_id:subId}},
    {
      '$set' : {
        'subs.$.name' : updateObj.name,
        'subs.$.price' : updateObj.price,
        ......
      }
    },
    {
      new : false,
      overwrite : true,
      runValidators: true
    }
  ).exec();
}
  1. Mongoose will add new _id whenever you replace/add a new object in an array. So update the values individually to avoid this.

Upvotes: 2

Related Questions