skip to Main Content

I need to remove some references to objects in each files section (section1, section2, section3, others).

Document example:

{
  "_id": "64a3268474aa29e72b40c521",
  "name": "Test",
  "description": "",
  "files": {
    "section1": [
      {
        "$oid": "64e617006e14fecb803b8bb3"
      },
      {
        "$oid": "64e5fba8742cefedd2897e9e"
      }
    ],
    "section2": [
      {
         "$oid": "64e5fba8742cefedd2897e98"
      }
    ],
    "section3": [],
    "others": []
  }
}

The IDs of the objects to be deleted are stored in an array filesToDeleteIds, each element of the array is responsible for a separate section.

Example array with IDs to be removed from the document:

`[
  ["64e5fba8742cefedd2897e9a", "64e5fba8742cefedd2897e9e"],
  ["64e5fba8742cefedd2897e98"],
  [],
  []
]`

I do it like this:

await this.myModel.updateOne(
      { _id: id },
      { $pull: {
        'files.section1': { _id: { $in: filesToDeleteIds[0] }},
        'files.section2': { _id: { $in: filesToDeleteIds[1] }},
        'files.section3': { _id: { $in: filesToDeleteIds[2] }},
        'files.others': { _id: { $in: filesToDeleteIds[3] }},
      }},
)

But it doesn’t work, there are no errors.
The updateOne function return this:

{
  acknowledged: true,
  modifiedCount: 1,
  upsertedId: null,
  upsertedCount: 0,
  matchedCount: 1
}

2

Answers


  1. To achieve the desired result, you should modify your update operation as follows:

    await this.myModel.updateOne(
      { _id: id },
      {
        $pull: {
          'files.section1': { $or: filesToDeleteIds[0].map(id => ({ $oid: id })) },
          'files.section2': { $or: filesToDeleteIds[1].map(id => ({ $oid: id })) },
          'files.section3': { $or: filesToDeleteIds[2].map(id => ({ $oid: id })) },
          'files.others': { $or: filesToDeleteIds[3].map(id => ({ $oid: id })) }
        }
      }
    );
    

    In this code, we’re using the $or operator to match multiple IDs within each section. The map function is used to convert each ID in the filesToDeleteIds array to the correct object structure with the "$oid" field.

    Login or Signup to reply.
  2. The Model.updateOne() return object you get can often be undesirable if you need to see the changes immediately without making another database request.

    I can see you have a solution already but if you wanted to get the document returned after you make the changes then you can use the {new:true} option with Model.findByIdAndUpdate() like so:

    // Convert your String Ids to ObjectIds
    for(const f of filesToDeleteIds){
       f.forEach((e, i) => {
          f[i] = new mongoose.Types.ObjectId(e);
       })
    }
    
    // Now do the update with the {new:true} option set
    await this.myModel.findByIdAndUpdate(
       id,
       {
          $pull: {
             'files.section1': {$in: filesToDeleteIds[0]},
             'files.section2': {$in: filesToDeleteIds[1]},
             'files.section3': {$in: filesToDeleteIds[2]},
             'files.others': {$in: filesToDeleteIds[3]},
          }
       },
       { new : true }
    );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search