如何在MongoDB中向匹配指定key值的嵌套对象数组内push数据
问题原因与修复方案
核心错误点
- arrayFilters格式不符合mongoose要求:
arrayFilters必须传入数组格式的过滤规则,你当前传入的是单个对象,导致嵌套数组匹配失败,不会执行更新操作。 - 默认返回旧文档:
findOneAndUpdate默认返回更新前的文档,即使更新成功你拿到的返回值也是旧数据,容易误判更新结果。 - 查询参数冗余引号:你在Insomnia中传递的
class参数值带了单引号'5A',但数据库中存储的class字段值为无引号的5A,过滤条件无法匹配到目标嵌套元素。
修复后代码
import db from "../models/index.js"; const Teacher = db.teacher const updateActivity = (req, res) => { const query = { _id: req.query.id }; const update = {$push: { 'classes.$[group].activities.in_progress': req.query.data } }; // 修复1:arrayFilters改为数组格式,同时清理class参数的冗余引号 const options = { arrayFilters: [ { 'group.class': req.query.class.replace(/['"]+/g, '') } ], // 修复2:新增new:true返回更新后文档,runValidators开启schema校验 new: true, runValidators: true }; Teacher.findOneAndUpdate(query, update, options).exec((err, data) => { if (err) { res.status(400).send({ message: err }); return; } res.status(200).send(data); }) } const API = { updateActivity } export default API
额外注意
- 你集合定义里
activities下的finisched为拼写错误,正确拼写应为finished,后续操作该字段时注意避免匹配失败。 - 测试时可以在Insomnia中直接传递
class=5A,不要加额外的单双引号,不需要额外做参数引号替换也能正常匹配。
内容的提问来源于stack exchange,提问作者RootAtKali
相关产品推荐
相关产品推荐

