1

I am currently using array filters to update the nested object. My structure is -

Category Collection - 
{
  name:Disease,
  _id:ObjectId,
  subCategory:[{
    name:Hair Problems,
    _id:ObjectId,
    subSubCategory:[{
       name: Hair Fall,
       _id:ObjectId
    },{
       name: Dandruff,
       _id:ObjectId
    }]
  }]
}

I want to update the subsubcategory with id 1.1.1 which I am doing by using array filters.

let query = { 'subCategories.subSubCategories._id': subSubId };
let update = { $set: { 'subCategories.$.subSubCategories.$[j]': data } };
let option = { arrayFilters: [{ 'j._id': subSubId }], new: true };

await Categories.findOneAndUpdate(query, update, option

This code is working fine but array filters change the object id of subsubCategory. Is there any other alternative to do so without changing the ObjectId.

Thanks in advance

2
  • Which property do you want to update exactly? Commented May 16, 2019 at 6:53
  • user can update any property present in subsubCategory @AmitDas Commented May 16, 2019 at 6:55

2 Answers 2

1

You can loop over the keys which you are getting as payload and put inside the $set operator.

const data = {
  firstKey: "key",
  secondKey: "key2",
  thirdKey: "key3"
}
const object = {}

for (var key in data) {
  object[`subCategories.$.subSubCategories.$[j].${key}`] = data[key]
}

let query = { 'subCategories.subSubCategories._id': subSubId };
let update = { '$set': object };
let option = { 'arrayFilters': [{ 'j._id': subSubId }], 'new': true };

await Categories.findOneAndUpdate(query, update, option)
Sign up to request clarification or add additional context in comments.

Comments

1

Problem is in $set line there you have not mentioned specific fields to be update instead subCategory.$.subSubCategory.$[j] will replace complete object element that matches the _id filter. Hence your _id field is also getting updated. You have to explicitly mention the field name after array element identifier. See example below:

Suppose you want to update name field in subSubCategories from Dandruff to new Dandruff. Then do this way:

let update = { $set: { 'subCategories.$.subSubCategories.$[j].name': "new Dandruff" } };

This will only update name field in subSubCategories array

1 Comment

I am updating multiple fields at the same time, so do i have to mention every field.

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.