Ajith
Ajith

Reputation: 2666

Mongoose - How to update certain subdocument value in array of objects

My collection sample data is as follows:

{
    "_id" : ObjectId("649d1b0b5e40905678a30829"),
    "slug" : "samsung-s22",
    "name" : "Samsung S22",
    "params" : [
        {
            "modelno" : "SM-S901B",
            "color"   : "White",
            "price"   : "64000",
            "_id"     : ObjectId("649e70bdd20e94bef90f2e7f")
        },
        {
            "modelno" : "SM-S901B",
            "color"   : "Black",
            "price"   : "64000",
            "_id"     : ObjectId("649e70bdd20e94bef90f2e7d")
        },
        {
            "modelno" : "SM-S901U",
            "color"   : "Black",
            "price"   : "74000",
            "_id"     : ObjectId("649e70bdd20e94bef90f2a7f")
        },
        {
            "modelno" : "SM-S901U",
            "color"   : "Black",
            "price"   : "74000",
            "_id"     : ObjectId("649e70bdd20e94bef90f2b7f")
        },
    ]
},
{
    "_id" : ObjectId("649d1b0b5e40905678a30819"),
    "slug" : "vivo-v19",
    "name" : "Vivo V19",
    "params" : [
        {
            "modelno" : "Vivo 1933",
            "color"   : "Grey",
            "price"   : "34000",
            "_id"     : ObjectId("659e70bdd20e94bef90f2e7f")
        },
        {
            "modelno" : "Vivo 1933",
            "color"   : "Black",
            "price"   : "34000",
            "_id"     : ObjectId("659e70bdd20e94bef90f2e7d")
        },
        {
            "modelno" : "Vivo 2933",
            "color"   : "Black",
            "price"   : "44000",
            "_id"     : ObjectId("659e70bdd20e94bef90f2a7f")
        },
    ]
}

What I need is to update specific model number's price value. For example in the above document, if I give condition as name = "Samsung S22" && "modelno" = "SM-S901B" and new price value as 69999, then I need to update the price value of the following params only:

{
    "modelno" : "SM-S901B",
    "color"   : "White",
    "price"   : "69999",
    "_id"     : ObjectId("649e70bdd20e94bef90f2e7f")
},
{
    "modelno" : "SM-S901B",
    "color"   : "Black",
    "price"   : "69999",
    "_id"     : ObjectId("649e70bdd20e94bef90f2e7d")
},

Upvotes: 0

Views: 60

Answers (1)

Yong Shun
Yong Shun

Reputation: 51450

You should update the element in the params array via filtered positional operator $[<identifier>].

db.collection.update({
  "name": "Samsung S22",
  "params.modelno": "SM-S901B"
},
{
  $set: {
    "params.$[param].price": "69999"
  }
},
{
  arrayFilters: [
    {
      "param.modelno": "SM-S901B"
    }
  ]
})

Demo @ Mongo Playground

For Mongoose:

You may use either of these update() methods depend on your use case:

await collection.findOneAndUpdate({
  "name": "Samsung S22",
  "params.modelno": "SM-S901B"
},
{
  $set: {
    "params.$[param].price": "69999"
  }
},
{
  arrayFilters: [
    {
      "param.modelno": "SM-S901B"
    }
  ]
})

Upvotes: 2

Related Questions