Mongoose中使用findOneAndUpdate实现布尔值切换的问题排查
问题分析与解决
问题根源
你的更新语句错误地将整个tasksItems数组替换成了单个对象,导致后续操作无法定位到数组元素:
原代码中的{ $set: { tasksItems: { done: { $eq: [false, "$done"] } } } }会把tasksItems字段从数组覆盖为仅包含done的对象,第一次操作后文档结构被破坏,第二次查询"tasksItems._id"自然找不到匹配项。
正确实现方式
方式一:使用数组定位操作符$(推荐简单场景)
利用MongoDB的$操作符定位匹配的数组元素,直接修改其done字段:
tasksModel.findOneAndUpdate( { "tasksItems._id": taskItemId }, { $set: { "tasksItems.$.done": { $not: "$tasksItems.$.done" } } }, { new: true } );
$not操作符直接对布尔值取反,实现true转false、false转true的切换逻辑。
方式二:使用聚合管道$map(适合复杂数组操作)
通过$map遍历数组,仅修改匹配_id的元素,保留数组结构:
tasksModel.findOneAndUpdate( { "tasksItems._id": taskItemId }, [ { $set: { tasksItems: { $map: { input: "$tasksItems", as: "item", in: { $cond: [ { $eq: ["$$item._id", mongoose.Types.ObjectId(taskItemId)] }, // 匹配到目标元素,切换done值 { ..."$$item", done: { $not: "$$item.done" } }, // 未匹配到,保持原元素不变 "$$item" ] } } } } } ], { new: true } );
注意:如果你的taskItemId是字符串类型,需要用mongoose.Types.ObjectId()转换为ObjectId,确保和数据库中的_id类型匹配。
内容的提问来源于stack exchange,提问作者david
相关产品推荐
相关产品推荐

