问题
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
}
回答1:
Please try using mongoose arrayFilters like this:
Car.update(
{ _id: carId },
{ $set: { "insurances.$[elem]": foundInsurance } },
{ arrayFilters: [ { 'elem._id': insuranceId } ] }
)
来源:https://stackoverflow.com/questions/62915677/update-nested-object-in-array-mongoose