Обновить объект MongoDB в объекте по идентификатору

#javascript #mongodb #mongoose #mongodb-query

#javascript #mongodb #мангуст #mongodb-запрос

Вопрос:

Модель:

 const projectSchema = new Schema({
  name: {
    type: String,
    maxlength: 50
  },
  description: {
    type: String
  },
  projectLead: {
    type: String
  },
  start: {
    type: String
  },
  end: {
    type: String
  },
  projectType: {
    type: String
  },
  claimId: {
    type: String
  },
  organization: {
    type: String
  },
  seats: [{
    id: String,
    employee: String,
    role: String,
    start: String,
    end: String,
    workload: Number,
    skills: Array,
    approved: Boolean
  }]
}, {
  timestamps: true
})
  

Пример ответа модели:

 {
    "project": {
        "_id": "5cab4b9bc9b29a7ba2363875",
        "name": "Project Title",
        "description": "Project description",
        "projectLead": "email@email",
        "start": "2018-06-01T09:45:00.000Z",
        "end": "2019-06-31T09:45:00.000Z",
        "claimId": "AIIIIII",
        "organization": "Company ACE",
        "seats": [
            {
                "skills": [
                    "Node.js",
                    "Vue.js"
                ],
                "_id": "5cab548e5cefe27ef82ca313",
                "start": "2018-06-01T09:45:00.000Z",
                "end": "2019-06-31T09:45:00.000Z",
                "role": "Developer",
                "approved": false,
                "workload": 20,
                "employee": ''
            }
        ],
        "createdAt": "2019-04-08T13:24:43.253Z",
        "updatedAt": "2019-04-08T14:02:54.257Z",
        "__v": 0
    }
}
  

Контроллер:

 exports.updateSeatEmployee = async (req, res, next) => {
  try {
    const project = await Project.findOneAndUpdate({
      "seats._id": req.params.id
    }, {
      "seats.employee": req.body.employee
    }, {
      new: true
    })
    console.log("project", project);
    return res.json({
      project: project
    })
  } catch (error) {
    next(error)
  }
}
  

Отладчик:

Mongoose: users.createIndex({ email: 1 }, { unique: true, background: true }) { sub: ‘5cab48ebec24577ab3329fcd’, iat: 1554729210 }

Mongoose: users.findOne({ _id: ObjectId(«5cab48ebec24577ab3329fcd») }, { проекция: {} })

Mongoose: projects.findAndModify({ ‘seats._id’: ObjectId(«5cab529bcafa027e30ee229c») }, [], { ‘$ setOnInsert’: { Дата создания: новая дата («Пн, 08 Апр 2019 14:45:56 GMT») }, ‘$set’: { ‘места.$.employee’: ’email@email.com ‘, обновлеНо: новая дата («Пн, 08 Апр 2019 14:45:56 GMT») } }, { new: true, upsert: false, удалить: false, проекция: {} }) (узел: 33302) Предупреждение об устаревании: коллекция.findAndModify устарел. Вместо этого используйте findOneAndUpdate, findOneAndReplace или findOneAndDelete .

project null

Я хочу выполнить поиск определенного объекта seats по его id . Это конкретное место должно быть обновлено. В моем случае я хочу обновить employee поле.

Если я выполняю a findOne({"seats._id": req.params.id}) , я возвращаю проект findOneAndUpdate , но возвращает null .

Ответ №1:

Вам нужен оператор $ positional, поскольку seats это массив, и вам следует использовать оператор $set, если вы хотите обновить только одно поле

 const project = await Project.findOneAndUpdate({
  "seats._id": req.params.id
}, {
  $set: { "seats.$.employee": req.body.employee }
}
  

Комментарии:

1. @mrks вы пробовали оба условия фильтрации, например { _id: ObjectId("5cab48ebec24577ab3329fcd"), "seats._id": req.params.id } ?