Mongoose - Modify array attribute elements in a Schema based on some Filter Criteria

Viewed 29

I am trying to update an array within the MemberSchema. I can't seem to select for the correct array elements, nor get the update query to work.

My schema is shown below. The array I am trying to update is MemberSchema.tasks

const MemberSchema = new Schema({
    name: {
        type: Member_NameSchema,
        required: true,
    },
    program: {
        type: String
    },
    bio: {
        type: String
    },
    ...
    tasks: {
        type: [Member_Task]
    },
});

const Member_Task = new Schema({
    taskId: {
        type: Schema.Types.ObjectId,
        required: true,
        ref: 'Task'
    },
    status: {
        type: String,
        required: true,
        enum: ['pending', 'complete', 'irrelevant']
    },
});

Here is my code to update the tasks array with the following samples values below:

return (await Member.updateOne(filter, body).exec());

filter:
{ _id: '5fb9a5e7befa50006c44aae0', // ID of the Member
  'tasks.taskId':
   { '$in':
      [ 5fb744af0e6264002db1076c,
        5fb73d030e6264002db1073c,
        5fb73e550e6264002db10742,
        5fb746e50e6264002db10776,
        5fb7475c0e6264002db1077c,
        5fb747940e6264002db10782, ] 
}}

body: { '$set': { 'tasks.$.status': 'pending' } }

I want to update ALL tasks that are in the list specified in filter { $in .... My query so far doesn't seem to work.

Update: I tried .updateMany, but that didn't seem to work. Note that I only want to update ONE member record, and as many tasks as possible that match the provided task ID list.

1 Answers

You can use arrayFitlers and need to convert string id to object id type using mongoose.Types.ObjectId,

return (await Member.updateOne(filter, body, options).exec());

filter: { _id: mongoose.Types.ObjectId('5fb9a5e7befa50006c44aae0') } // ID of the Member

body: { $set: { 'tasks.$[t].status': 'pending' } }

taskIds = [ "5fb744af0e6264002db1076c",
        "5fb73d030e6264002db1073c",
        "5fb73e550e6264002db10742",
        "5fb746e50e6264002db10776",
        "5fb7475c0e6264002db1077c",
        "5fb747940e6264002db10782" ]

taskIds.map(taskId => mongoose.Types.ObjectId(taskId));

options: { 
  arrayFilters: [{ 
    "t.taskId": {  $in: taskIds }
  }]
}

Playground

Related