【问题标题】:Update nested object after matching id of main document and nested object匹配主文档和嵌套对象的 id 后更新嵌套对象
【发布时间】:2020-06-20 19:21:20
【问题描述】:

我有以下mongo文档结构

{
    "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,我的目标是通过匹配检查ID 来更新病人的检查。 这是我的控制器。

/**
 * 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)
    }
  })
}

我参考了Selecting and updating a nested object by it's ObjectId in Mongoose.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
      }
    }
  }

并在arrayFilters上使用'exam.id'

【问题讨论】:

  • 如果您在arrayFilters 中使用examinations,则必须在update 中指定examinations[examinations]。也许你应该重命名为examinations[exam]exam._id 以避免混淆
  • @thammada.ts 谢谢你的时间,你能分享我应该怎么做吗。
  • @thammada.ts 我明白了。非常感谢。
  • 我已经发布了一个答案,但我没有看到你对这个问题的更新:)。还在查询部分添加了一些提示

标签: node.js mongodb mongoose


【解决方案1】:

你必须改变你的updateoptions如下

/*
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)
}

【讨论】:

  • 我不知道为什么,但是按照这个答案,考试的_id被改变了。
  • 哦,因为我们在推送一个全新的文档,请看我在代码开头的注释中的解释。我将添加相同的 _id 回来
猜你喜欢
  • 1970-01-01
  • 2021-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-14
  • 2016-02-20
  • 2021-12-15
相关资源
最近更新 更多