如何使用Node.js+Express为MongoDB数组的最后一个对象添加新字段
解决方案
你之前使用$push不符合需求是因为该操作符的作用是给数组新增元素,而非修改数组内已有元素的字段,你可以通过以下方案实现需求:
方案1(MongoDB 5.0+ 推荐)
MongoDB 5.0及以上版本支持直接用-1负索引定位数组的最后一个元素,配合$set操作符即可在保留原有字段的基础上,给最后一个对象新增字段,node.js环境下的代码示例如下:
// 以原生MongoDB驱动为例,Mongoose写法完全一致 const result = await yourCollection.updateOne( // 第一个参数:文档查询条件,根据你的实际业务调整,增加数组非空判断避免异常 { _id: yourDocumentId, dailyReadings: { $exists: true, $ne: [] } }, // 第二个参数:更新逻辑 { $set: { // 按你的需求新增任意字段,原有heartRate字段不会被改动 "dailyReadings.-1.bloodPressure": 120, "dailyReadings.-1.steps": 7800, "dailyReadings.-1.otherCustomField": "your value" } } )
如果是配合Express接收桌面端提交的数据,可以直接把请求参数映射到更新字段:
app.post('/update-latest-reading', async (req, res) => { const { userId, bloodPressure, steps } = req.body await UserModel.updateOne( { _id: userId, dailyReadings: { $exists: true, $ne: [] } }, { $set: { "dailyReadings.-1.bloodPressure": bloodPressure, "dailyReadings.-1.steps": steps } } ) res.send({ status: 'success' }) })
方案2(MongoDB 4.2+ 兼容低版本)
如果你使用的MongoDB版本低于5.0不支持负索引,可以使用聚合更新管道实现相同效果:
await yourCollection.updateOne( { _id: yourDocumentId, dailyReadings: { $exists: true, $ne: [] } }, [ { $set: { dailyReadings: { $concatArrays: [ // 保留数组除最后一个外的所有元素 { $slice: [ "$dailyReadings", 0, { $subtract: [ { $size: "$dailyReadings" }, 1 ] } ] }, // 合并最后一个元素的原有字段和新增字段 [ { $mergeObjects: [ { $last: "$dailyReadings" }, { bloodPressure: 120, steps: 7800 } // 你的新增字段 ] } ] ] } } } ] )
内容的提问来源于stack exchange,提问作者SA Master
相关产品推荐
相关产品推荐

