Mongoose — изменение элементов атрибутов массива в схеме на основе некоторых критериев фильтрации

#mongodb #mongoose

#mongodb #mongoose

Вопрос:

Я пытаюсь обновить массив внутри MemberSchema . Кажется, я не могу выбрать правильные элементы массива и не заставить запрос обновления работать.

Моя схема показана ниже. Массив, который я пытаюсь обновить, является 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']
    },
});
 

Вот мой код для обновления массива задач следующими примерами значений ниже:

 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' } }
 

Я хочу обновить ВСЕ задачи, которые находятся в списке, указанном в filter { $in ... . Мой запрос пока, похоже, не работает.

Обновление: я пытался .updateMany , но, похоже, это не сработало. Обратите внимание, что я хочу обновить только ОДНУ запись участника и как можно больше задач, которые соответствуют предоставленному списку идентификаторов задач.

Ответ №1:

Вы можете использовать arrayFitlers и вам нужно преобразовать идентификатор строки в тип идентификатора объекта с помощью 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 }
  }]
}
 

Игровая площадка