Search code examples
javascriptnode.jsmongodbmongooseodm

Updating a nested object in a document using mongoose


I've been trying to update a particular object in a Mongodb document without any luck using the findOneAndUpdate() method. This is what my collectiom looks like

{
  _id: new ObjectId("61da0ab855483312e8f4483b"),
  products: [
    {
      createdAt: 2022-01-08T22:05:44.635Z,
      _id: new ObjectId("61da0ab855483312e8f4483c"),
      productCode: 'otf',
      productName: 'facebookmeta',
      claims: [Array],
      permissions: []
    },
    {
      createdAt: 2022-01-08T22:05:44.635Z,
      _id: new ObjectId("61da0ab855483312e8f4483f"),
      productCode: '4pf',
      productName: 'twitteroauth',
      claims: [Array],
      permissions: [Array]
    }
  ],
  __v: 0
}

When i try something like this. i am trying to find a singular object based on its product code and update that object

ProductModel.findOneAndUpdate({productCode: userData.productCode}, dataToBeUpdated, {new: true})

it returns a

Performing an update on the path '_id' would modify the immutable field '_id

i am suspecting that MongoDB is applying query conditions on collection and returns the result with the matching documents so its probably returning both objects which is probably the cause of the error i am encountering but i could be wrong.

How can i efficiently point it to the right object and perform an update


Solution

  • MongoDB supports the single-level deep update of subdocument using positional operator ($).

    db.collection_name.update({
        _id: ObjectId("61da0ab855483312e8f4483b"),
        "products.productCode": "4pf"
    },
    {
        "$set": {
            "products.$.productName": "twitteroauth name updated"
        }
    })
    

    In the above update clause, $ will be replaced by the matching index of a subdocument at a runtime.

    For example $ will be replaced by value 1 at a runtime because of "products.productCode": "4pf" condition

    Please note the below points:

    1. You must include the array field as part of the query document.
    2. The positional operator cannot be used for updates inside of a nested array.

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