Search code examples
node.jsmongoose

How can I update multiple array object field in mongoose?


My mongoose schema is structured this way

 {
        "user": "63bue258j43747143hi059d7",
        "images": [
            {
                "image_link": "first-unique-link-http::link-to-image1-63",
                "inStock": false
            },
            {
                "image_link": "second-unique-link-http::link-to-image2-63",
                "inStock": false
            },
            {
                "image_link": "third-unique-link-http::link-to-image3-63",
                "inStock": false
            }
        ]
    },
    {
        "user": "9Ef53258j4374714phk625b3",
        "images": [
            {
                "image_link": "anotherFirst-unique-link-http::link-to-image1-9E",
                "inStock": false
            },
            {
                "image_link": "anotherSecond-unique-link-http::link-to-image2-9E",
                "inStock": false
            }
        ]
    }

I want to query my mongoose database to update all inStock fields that matches the array which conatins the image_link to false.

What I want to achieve is something like this query below

const imgArr = ['first-unique-link-http::link-to-image1-63', 'third-unique-link-http::link-to-image3-63', 'anotherSecond-unique-link-http::link-to-image2-9E']
const updateStockStatus = await ImageStock.update(
    { "images.image_link": { $in: imgArr } },
    { $set: { 'images.inStock' : true } },
    {multi: true}
 )

So after running the query my mongoose schema should look like this

{
        "user": "63bue258j43747143hi059d7",
        "images": [
            {
                "image_link": "first-unique-link-http::link-to-image1-63",
                "inStock": true
            },
            {
                "image_link": "second-unique-link-http::link-to-image2-63",
                "inStock": false
            },
            {
                "image_link": "third-unique-link-http::link-to-image3-63",
                "inStock": true
            }
        ]
    },
    {
        "user": "9Ef53258j4374714phk625b3",
        "images": [
            {
                "image_link": "anotherFirst-unique-link-http::link-to-image1-9E",
                "inStock": false
            },
            {
                "image_link": "anotherSecond-unique-link-http::link-to-image2-9E",
                "inStock": true
            }
        ]
    }

Solution

  • You can use arrayFilters like this:

    With arrayFilters you are telling mongo: "for the array images set only these ones where elem matches with predefined one". And elem is the objects where image_link is in the array.

    db.collection.updateMany({},
    {
      "$set": {
        "images.$[elem].inStock": true
      }
    },
    {
      "arrayFilters": [
        {
          "elem.image_link": {
            "$in": imgArr
          }
        }
      ]
    })
    

    Example here