更新数组Mongoose中的嵌套对象 [英] update nested object in array Mongoose

查看:53
本文介绍了更新数组Mongoose中的嵌套对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望更新ID为 5f0e14241f5ccb42d8742767 的嵌套对象:

  {"_id":"5f0b33ab52a4e966c754d963","make":"Toyota","model":"Prius","engine":"1.8",保险":[{"yearlyPremium":{"$ numberDecimal":"60.39"},"_id":"5f0e14241f5ccb42d8742767","startDate":"1970-01-19T09:31:15.550Z","monthlyPremium":{"$ numberDecimal":"5.49";},多余":100},{"yearlyPremium":{"$ numberDecimal":"71.39"},"_id":"5f0e147c0340243eb03b5247","startDate":"1970-01-19T09:31:15.550Z","monthlyPremium":{"$ numberDecimal":"6.49";},多余":100},]} 

因此,在我的PATCH rest api请求中,我只想将每月保费从当前的 5.49 更改为 1.50 .因此,我将 carId:5f0b33ab52a4e966c754d963 和特定的 inusranceId:5f0e14241f5ccb42d8742767 (嵌套在Car对象中)传递为查询参数,以标识需要更新保险阵列中的哪一种保险.然后在请求正文中传递要修改的项目( monthlyPremium ):

我遵循了堆栈溢出解决方案: mongoDB:更新嵌套数组对象

这就是我尝试过的:

  router.route('/insurance').patch(async(req,res)=> {const {carId,insuranceId} = req.queryconst {startDate,MonthlyPremium,超额} = req.body尝试 {const foundCar =等待Car.findById(carId)const foundCar = foundCar.insurances.filter(ins => {返回ins._id == insuranceId})foundInsurance.startDate = startDate&&新日期(startDate * 1000)||foundInsurance.startDate,foundInsurance.monthlyPremium =每月Premium&&parseFloat(monthlyPremium)||foundInsurance.monthlyPremium,foundInsurance.yearlyPremium =每月Premium&&parseFloat(monthlyPremium)* 12 ||foundInsurance.yearlyPremium,foundInsurance.excess =多余的&&数量(多余)||foundInsurance.excessCar.update({_id:carId,"insurances._id":insuranceId},{$ set:{"insurances.$":foundInsurance}})res.send(`保险已更新`)} catch(err){res.status(400).json({错误:err})}}) 

在代码中正确捕获了请求查询.请求成功并返回保险已更新,但未更新任何内容.一切正常,但更新方法未将信息 monthlyPremium 更新为 1.50 .

更新

@Mahan,我尝试了您建议的方法,但不幸的是,记录仍然没有改变.打印 foundInsurance 我明白了(它不打印控制台中的值,仅打印元数据):

 找到了保险:{AnnualPremium:Decimal128 {_bsontype:"Decimal128",字节:<缓冲区97 17 00 00 00 00 00 00 00 00 00 00 00 00 3c 30>},_id:5f0e14241f5ccb42d8742767,开始日期:1970-01-19T09:31:15.550Z,MonthlyPremium:Decimal128 {_bsontype:"Decimal128",字节:<缓冲器25 02 00 00 00 00 00 00 00 00 00 00 00 00 3c 30>},超额:100} 

解决方案

请尝试使用像这样的猫鼬 arrayFilters :

  Car.update({_id:carId},{$ set:{"insurances.$ [elem]":foundInsurance}},{arrayFilters:[{'elem._id':insuranceId}]}) 

I would like the nested object with the id 5f0e14241f5ccb42d8742767 to be updated:

 {
        "_id": "5f0b33ab52a4e966c754d963",
        "make": "Toyota",
        "model": "Prius",
        "engine": "1.8",
        "insurances": [
            {
                "yearlyPremium": {
                    "$numberDecimal": "60.39"
                },
                "_id": "5f0e14241f5ccb42d8742767",
                "startDate": "1970-01-19T09:31:15.550Z",
                "monthlyPremium": {
                    "$numberDecimal": "5.49"
                },
                "excess": 100
            },
            {
                "yearlyPremium": {
                    "$numberDecimal": "71.39"
                },
                "_id": "5f0e147c0340243eb03b5247",
                "startDate": "1970-01-19T09:31:15.550Z",
                "monthlyPremium": {
                    "$numberDecimal": "6.49"
                },
                "excess": 100
            },
       ]
 }

So in my PATCH rest api request, I just want to change the monthly premium, from what it is currently 5.49 to 1.50. Hence I pass the carId: 5f0b33ab52a4e966c754d963 and the particular inusranceId: 5f0e14241f5ccb42d8742767 (nested in Car object) as query params, to identify which insurance in the insurances array needs updating. Then in the request body I pass the item to be modified (monthlyPremium):

I followed the stack overflow solution: mongoDB: Update nested array object

So this is what I tried:

router.route('/insurance')
.patch(async (req, res) => {
    const { carId, insuranceId } = req.query
    const { startDate, monthlyPremium, excess } = req.body
    try {
        const foundCar = await Car.findById(carId)
        const foundCar = foundCar.insurances.filter(ins => {
            return ins._id == insuranceId
        })
        
        foundInsurance.startDate = startDate && new Date(startDate * 1000) || foundInsurance.startDate,
        foundInsurance.monthlyPremium = monthlyPremium && parseFloat(monthlyPremium) || foundInsurance.monthlyPremium,
        foundInsurance.yearlyPremium = monthlyPremium && parseFloat(monthlyPremium) * 12 || foundInsurance.yearlyPremium,
        foundInsurance.excess = excess && Number(excess) || foundInsurance.excess
        
        Car.update(
            {_id: carId, "insurances._id": insuranceId}, 
            {$set: {"insurances.$":foundInsurance}}
        )

        res.send(`Insurance updated`)
    } catch (err) {
        res.status(400).json({ error: err })
    }
})

The request queries are captured correctly in the code. The request succeeds and returns Insurance updated, but nothing gets updated. Everything is working except the update method is not updating the info monthlyPremium to 1.50.

UPDATE

@Mahan, I tried your suggested approach, unfortunately the record still hasn't changed. Printing foundInsurance I get this (it doesn't print the values in the console, just the meta data):

found insurance: {
  yearlyPremium: Decimal128 {
    _bsontype: 'Decimal128',
    bytes: <Buffer 97 17 00 00 00 00 00 00 00 00 00 00 00 00 3c 30>
  },
  _id: 5f0e14241f5ccb42d8742767,
  startDate: 1970-01-19T09:31:15.550Z,
  monthlyPremium: Decimal128 {
    _bsontype: 'Decimal128',
    bytes: <Buffer 25 02 00 00 00 00 00 00 00 00 00 00 00 00 3c 30>
  },
  excess: 100
}

解决方案

Please try using mongoose arrayFilters like this:

Car.update(
  { _id: carId }, 
  { $set: { "insurances.$[elem]": foundInsurance } },
  { arrayFilters: [ { 'elem._id': insuranceId } ] }
)

这篇关于更新数组Mongoose中的嵌套对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆