Обновить вложенный объект после сопоставления идентификатора основного документа и вложенного объекта - PullRequest
2 голосов
/ 20 июня 2020

У меня есть следующая структура mon go document

{
    "registrationDate": "2020-06-09T18:15:00.000Z",
    "_id": "5ee6dd003a97c93c6436349c",
    "ofSite": "5ee19fe085d70733243c3309",
    "patientID": "NGH-123",
    "neocareID": "",
    "babyName": "Joey",
    "motherName": "Phoebe",
    "dateOfBirth": "2020-06-08T18:15:00.000Z",
    "babySex": "Female",
    "birthType": "Single",
    "patientType": "Referred",
    "mobileNumber": "9802824412",
    "mobileOf": "Family Member",
    "linkedFCHV": "Racheal",
    "FCHVmobile": "9876225420",
    "address": "Holloywood",
    "examinations": [
        {
            "ODExam": {
                "plusODExam": "No",
                "zoneODExam": "I",
                "ropODExam": "No",
                "ropODStage": 1,
                "categoryOD": "None",
                "apROPOD": "Yes"
            },
            "OSExam": {
                "plusOSExam": "No",
                "zoneOSExam": "I",
                "ropOSExam": "Yes",
                "ropOSStage": 1,
                "categoryOS": "None",
                "apROPOS": "Yes"
            },
            "FindingFollowUp": {
                "ropFindings": "All Good so far",
                "followUpPlan": "Follow up in next month",
                "nameOfExaminer": "Luzan",
                "followUpDate": "2020-07-07T18:15:00.000Z"
            },
            "_id": "5ee6dd793a97c93c6436349e",
            "examinationDate": "06/12/2020",
            "currentPMA": 5,
            "daysOfLife": 42,
            "currentWeight": 4500,
            "visitType": "First"
        },
        {
            "ODExam": {
                "plusODExam": "No",
                "zoneODExam": "I",
                "ropODExam": "No",
                "ropODStage": 1,
                "categoryOD": "None",
                "apROPOD": "Yes"
            },
            "OSExam": {
                "plusOSExam": "No",
                "zoneOSExam": "I",
                "ropOSExam": "Yes",
                "ropOSStage": 1,
                "categoryOS": "None",
                "apROPOS": "Yes"
            },
            "FindingFollowUp": {
                "ropFindings": "All Good so far",
                "followUpPlan": "Follow up in next month",
                "nameOfExaminer": "Luzan",
                "followUpDate": "2020-07-07T18:15:00.000Z"
            },
            "_id": "5ee6dd913a97c93c643634a0",
            "examinationDate": "06/12/2020",
            "currentPMA": 5,
            "currentWeight": 4500,
            "visitType": "First"
        },
        {
            "ODExam": {
                "plusODExam": "No",
                "zoneODExam": "I",
                "ropODExam": "No",
                "ropODStage": 1,
                "categoryOD": "None",
                "apROPOD": "Yes"
            },
            "OSExam": {
                "plusOSExam": "No",
                "zoneOSExam": "I",
                "ropOSExam": "Yes",
                "ropOSStage": 1,
                "categoryOS": "None",
                "apROPOS": "Yes"
            },
            "FindingFollowUp": {
                "ropFindings": "All Good so far",
                "followUpPlan": "Follow up in next month",
                "nameOfExaminer": "Luzan",
                "followUpDate": "2020-07-07T18:15:00.000Z"
            },
            "_id": "5ee6ddf13a97c93c643634a2",
            "examinationDate": "06/12/2020",
            "currentPMA": 5,
            "currentWeight": 4500,
            "visitType": "First"
        },
        {
            "ODExam": {
                "plusODExam": "No",
                "zoneODExam": "I",
                "ropODExam": "No",
                "ropODStage": 1,
                "categoryOD": "None",
                "apROPOD": "Yes"
            },
            "OSExam": {
                "plusOSExam": "No",
                "zoneOSExam": "I",
                "ropOSExam": "Yes",
                "ropOSStage": 1,
                "categoryOS": "None",
                "apROPOS": "Yes"
            },
            "FindingFollowUp": {
                "ropFindings": "All Good so far",
                "followUpPlan": "Follow up in next month",
                "nameOfExaminer": "Luzan",
                "followUpDate": "2020-07-07T18:15:00.000Z"
            },
            "_id": "5ee6de093a97c93c643634a4",
            "examinationDate": "06/12/2020",
            "currentPMA": 5,
            "currentWeight": 4500,
            "visitType": "First"
        }
    ],
    "__v": 4
}

Позвольте мне рассказать вам, что я пытаюсь здесь сделать. Это мой маршрут

adminRoutes.post(
  '/examination/:patientID/:examID',
  userController.ensureAuthenticated,
  examController.findOneAndUpdate
)

Я передаю _id пациента как :patientID (документ) и _id вложенного объекта обследования как :examID, моя цель - обновить обследование пациента путем сопоставления идентификатора обследования. Это мой контроллер.

/**
 * POST /admin/examination/:patientID/:examID
 **/
exports.findOneAndUpdate = function (req, res) {
  const query = { examinations: { $elemMatch: { _id: new ObjectId(req.params.examID) } } }
  const update = {
    $set: {
      examinationDate: req.body.examinationDate,
      daysOfLife: req.body.daysOfLife,
      currentPMA: req.body.currentPMA,
      currentWeight: req.body.currentWeight,
      visitType: req.body.visitType,
      ODExam: {
        plusODExam: req.body.plusODExam,
        zoneODExam: req.body.zoneODExam,
        ropODExam: req.body.ropODExam,
        ropODStage: req.body.ropODStage,
        categoryOD: req.body.categoryOD,
        apROPOD: req.body.apROPOD
      },
      OSExam: {
        plusOSExam: req.body.ropOSExam,
        zoneOSExam: req.body.zoneOSExam,
        ropOSExam: req.body.ropOSExam,
        ropOSStage: req.body.ropOSStage,
        categoryOS: req.body.categoryOS,
        apROPOS: req.body.apROPOS
      },
      FindingFollowUp: {
        ropFindings: req.body.ropFindings,
        followUpPlan: req.body.followUpPlan,
        nameOfExaminer: req.body.nameOfExaminer,
        followUpDate: req.body.followUpDate
      }
    }
  }
  const options = { arrayFilters: [{ 'examinations._id': new ObjectId(req.params.examID) }] }
  Patient.updateOne(query, update, options, function (err, result) {
    if (err) {
      console.log(err)
      res.send(err)
    } else {
      console.log(result)
      res.send(result)
    }
  })
}

Я взял ссылку из Выбор и обновление вложенного объекта по его ObjectId в Mon goose. js. Но я получаю сообщение об ошибке.

MongoError: The array filter for identifier 'examinations' was not used in the update { $set: { daysOfLife: 45 } }

Я делаю это в изношенном состоянии, что могло бы быть эффективным способом обновить одно обследование в этом случае. И это правильный способ обновить только те данные, которые были изменены? Спасибо, что уделили время чтению.

Обновление [решено]. Я исправил это с помощью комментария @ thammada.ts. Все благодаря ему. Изменил мое обновление как:

const update = {
    $set: {
      'examinations.$[exam].examinationDate': req.body.examinationDate,
      'examinations.$[exam].daysOfLife': req.body.daysOfLife,
      'examinations.$[exam].currentPMA': req.body.currentPMA,
      'examinations.$[exam].currentWeight': req.body.currentWeight,
      'examinations.$[exam].visitType': req.body.visitType,
      'examinations.$[exam].ODExam': {
        plusODExam: req.body.plusODExam,
        zoneODExam: req.body.zoneODExam,
        ropODExam: req.body.ropODExam,
        ropODStage: req.body.ropODStage,
        categoryOD: req.body.categoryOD,
        apROPOD: req.body.apROPOD
      },
      'examinations.$[exam].OSExam': {
        plusOSExam: req.body.ropOSExam,
        zoneOSExam: req.body.zoneOSExam,
        ropOSExam: req.body.ropOSExam,
        ropOSStage: req.body.ropOSStage,
        categoryOS: req.body.categoryOS,
        apROPOS: req.body.apROPOS
      },
      'examinations.$[exam].FindingFollowUp': {
        ropFindings: req.body.ropFindings,
        followUpPlan: req.body.followUpPlan,
        nameOfExaminer: req.body.nameOfExaminer,
        followUpDate: req.body.followUpDate
      }
    }
  }

и использовал 'exam.id' в arrayFilters.

1 Ответ

1 голос
/ 20 июня 2020

Вы должны изменить свои update и options следующим образом

/*
Keep in mind that this will replace the whole element,
if you have other fields not included in the update, they will be removed.
To update new fields without replacing the element,
you have to specify all the fields like this

{
  $set: {
...
    "examinations.$[exam].examinationDate": req.body.examinationDate,
    "examinations.$[exam].daysOfLife": req.body.daysOfLife,

...
    "examinations.$[exam].ODExam.plusODExam": req.body.plusODExam,
    "examinations.$[exam].ODExam.zoneODExam": req.body.zoneODExam
...
  }
}
*/
const update = {
  $set: {
    "examinations.$[exam]": {
      _id: new ObjectId(req.params.examID),
      examinationDate: req.body.examinationDate,
      daysOfLife: req.body.daysOfLife,
      currentPMA: req.body.currentPMA,
      currentWeight: req.body.currentWeight,
      visitType: req.body.visitType,
      ODExam: {
        plusODExam: req.body.plusODExam,
        zoneODExam: req.body.zoneODExam,
        ropODExam: req.body.ropODExam,
        ropODStage: req.body.ropODStage,
        categoryOD: req.body.categoryOD,
        apROPOD: req.body.apROPOD
      },
      OSExam: {
        plusOSExam: req.body.ropOSExam,
        zoneOSExam: req.body.zoneOSExam,
        ropOSExam: req.body.ropOSExam,
        ropOSStage: req.body.ropOSStage,
        categoryOS: req.body.categoryOS,
        apROPOS: req.body.apROPOS
      },
      FindingFollowUp: {
        ropFindings: req.body.ropFindings,
        followUpPlan: req.body.followUpPlan,
        nameOfExaminer: req.body.nameOfExaminer,
        followUpDate: req.body.followUpDate
      }
    }
  }
}
const options = {
  arrayFilters: [{ 'exam._id': new ObjectId(req.params.examID) }]
}

Совет: вам действительно не нужно использовать $elemMatch в вашем запросе. Вы можете сделать

const query = { "examinations._id": new ObjectId(req.params.examID) }

Или, чтобы убедиться, что он обновляет правильного пациента

const query = {
  "_id": new ObjectId(req.params.patientID),
  "examinations._id": new ObjectId(req.params.examID)
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...