2

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.

8
  • yes working and how to update the multiple of values Commented Feb 2, 2021 at 7:54
  • No,They took single payload and updated multiple of fields. In this case I should take multiple of payload and should update the multiple of fields Commented Feb 2, 2021 at 9:10
  • Show the query with both vegetables. The one that doesn't work. Commented Feb 2, 2021 at 9:49
  • { "$and": [ { id: 1 }, { "products.name": [ "Onion", "Tomato" ] } ] } Commented Feb 2, 2021 at 10:16
  • You will need a map between old name and updated name for each name at least. Commented Feb 3, 2021 at 14:52

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.