skip to Main Content

I have the following schema:

const itemsSchema = new mongoose.Schema({
    name: String,
    checkedValue: String
});

const listSchema = new mongoose.Schema({
    name: String,
    items: [itemsSchema]
});

I want to update data like this: listSchema>items>checkedValue. I have performed the following operation:

db.collections.update({
  "name": "Home"
},
{
  "$set": {
    "items.$[i].checkedValue": "On"
  }
},
{
  arrayFilters: [
    {
      "i.items._id": ObjectId("646ec7836f8ba817e80e3372")
    }
  ]
})

But I am getting an error no document found. How can I update the specific document?

Sample data:

[
  {
    _id: ObjectId("646ec7916f8ba817e80e3377"),
    name: 'Home',
    items: [
      {
        name: 'home 1',
        checkedValue: 'Off',
        _id: ObjectId("646ec7966f8ba817e80e3380")
      },
      {
        name: 'home 2',
        checkedValue: 'Off',
        _id: ObjectId("646ec79a6f8ba817e80e338c")
      },
      {
        name: 'home 3',
        checkedValue: 'Off',
        _id: ObjectId("646efd38b1bc960c52ce5078")
      }
    ],
    __v: 3
  },
  {
    _id: ObjectId("646ed4136f8ba817e80e339b"),
    name: 'School',
    items: [
      {
        name: 'School 1',
        checkedValue: 'Off',
        _id: ObjectId("646efd45b1bc960c52ce509c")
      },
      {
        name: 'School 2',
        checkedValue: 'Off',
        _id: ObjectId("646efd4cb1bc960c52ce50a9")
      },
      {
        name: 'School 3',
        checkedValue: 'Off',
        _id: ObjectId("646efd52b1bc960c52ce50b1")
      }
    ],
    __v: 4
  }
]

3

Answers


  1. Chosen as BEST ANSWER

    When sending value to the arrayFilter, I have to convert the _id to an ObjectId. This is done by the following code:

    const checkedItemId = req.body.checkedItemId;
    const checkedItemObjectId = new mongoose.Types.ObjectId(checkedItemId);
    

    And to update the value in the subdocument, the following updateOne() method worked fine for me:

                    List.collection.updateOne(  
                        { 'items.checkedValue': 'Off' },
                        { '$set': { 'items.$[element].checkedValue': 'On' } },
                        {
                          arrayFilters: [
                            {
                              'element._id': { '$eq': checkedItemObjectId }
                            }
                          ]
                        })
    

  2. the object id you gave in the array filter is not in the items list. anyway even if it did the way you have written arrayFilters has to be changed to i._id. Think of i as an individual element in the items array

    db.collection.update({
      name: "Home"
    },
    {
      $set: {
        "items.$[i].checkedValue": "On"
      }
    },
    {
      arrayFilters: [
        {
          "i._id": ObjectId("646ec7966f8ba817e80e3380")
        }
      ]
    })
    

    playground

    Login or Signup to reply.
  3. First of all, your written query is incorrect as my perspective. Because you have used db.collections.update({ }). In here, it should be db.collection.update({ })

    After that, to perform the query you need to write it as,

    arrayFilters: [
        {
          "i._id": ObjectId("646ec7966f8ba817e80e3380")
        }
      ]
    

    Then your first index item will be updated.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search