提问者:小点点

更新Mongoose数组中的嵌套对象


我希望更新id为5F0E14241F5CCB42D8742767的嵌套对象:

 {
        "_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
            },
       ]
 }

所以在我的补丁rest api请求中,我只想更改每月溢价,从当前的5.49改为1.50。 因此,我将carid:5f0b33ab52a4e966c754d963和特定的inusranceid:5f0e14241f5ccb42d8742767(嵌套在Car对象中)作为查询参数传递,以识别insurances数组中的哪些保险需要更新。 然后在请求正文中传递要修改的项(monthlypremium):

我遵循了堆栈溢出解决方案:MongoDB:Update嵌套数组对象

所以这就是我尝试的:

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

在代码中正确地捕获了请求查询。 请求成功并返回Insurance Updated,但没有任何内容得到更新。 除了update方法没有将infoMonthlyPremium更新为1.50之外,其他一切都正常工作。

更新

@马汉,我尝试了你建议的做法,可惜记录还是没有改变。 打印FoundInsurance我知道了(它不打印控制台中的值,只打印元数据):

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
}

共1个答案

匿名用户

请尝试使用mongooseArrayFilters,如下所示:

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