How to bulk update the array of values in MongoDB?

Viewed 409

I have an array of values to update with existing array. I tried with $set it throws a error. If I have an array of values to update it should update matching item in the array.

1.If I have following documents in a collection

table

[
  {
    "id": 1,
    "name": "Fresh Mart",
    "products": [
      {
        "name": "Onion",
        "qty": 10,
        "price": "85"
      },
      {
        "name": "Tomato",
        "qty": 10,
        "price": "85"
      }
    ]
  },
  {
    "id": 2,
    "name": "Alfred super market",
    "products": [
      {
        "name": "Onion",
        "qty": 10,
        "price": "85"
      },
      {
        "name": "Tomato",
        "qty": 10,
        "price": "85"
      }
    ]
  }
]


Following query updates one product in first document:

Query

db.collection.update({
  "$and": [
    {
      id: 1
    },
    {
      "products.name": "Onion"
    }
  ]
},
{
  "$set": {
    "products.name": "Onion Updated"
  }
})

I tried to update both products in the first document with following query:

db.collection.update({
  "$and": [
    {
      id: 1
    },
    {
      "products.name":  [ "Onion", "Tomato" ] 
    }
  ]
},
{
  "$set": {
    "products.name": "Onion Updated"
  }
})
db.collection.update({
  id: 1
},
{
  "$addToSet": {
    "products": {
      "$each": [
        {
          "name": "Onion Updated",
          "qty": 10,
          "price": "85"
        },
        {
          "name": "Tomato Updated",
          "qty": 10,
          "price": "85"
        }
      ]
    }
  }
})

I used $addToSet it will not allow the duplicates. Is possible to replace existing value with $addToSet but it didn't update the document.

1 Answers

This answer is the dynamic approach of this answer https://stackoverflow.com/a/49870042/8987128

  • Configure your payload
let id = 1;
let updateName = [
  {
    oldName: "Onion",
    newName: "Onion Updated"
  },
  {
    oldName: "Tomato",
    newName: "Tomato Updated"
  },
];
  • Prepare arrayFilters and set conditions
let arrayFilters = [];
let set = {};

updateName.forEach((v, i) => {
  arrayFilters.push({ ["p"+i]: v.oldName });
  set["products.$[p"+i+"].name"] = v.newName;
});
  • Update query
db.collection.update(
  { id: id },
  { $set: set },
  { arrayFilters: arrayFilters }
)

Playground

Related