MongoDB通过_id删除subAssemblies嵌套数据失败如何解决
问题原因
- 逻辑错误:
deleteOne是用于删除MongoDB中整个集合文档的方法,你要操作的是删除文档内嵌套数组的指定元素,不属于删除整文档的场景。 - 匹配条件错误:你传入的
req.params.id是subAssemblies数组下嵌套对象的_id,不是外层travelers文档的_id,用这个id匹配外层文档自然找不到对应记录,所以返回n:0没有匹配到数据。
修改方案
你需要使用MongoDB的$pull操作符,更新匹配的外层文档,删除数组中符合条件的嵌套元素,提供两种实现方案:
方案1:仅通过subAssembly的id删除(无需外层文档id)
直接修改控制器代码即可:
deleteOneSubassembly: async (req, res) => { try { // 转换字符串id为MongoDB ObjectId类型,避免匹配失败 const ObjectId = require('mongoose').Types.ObjectId; const subId = new ObjectId(req.params.id); const removeOne = await Traveler.updateOne( // 匹配包含该subAssembly的外层文档 { "subAssemblies._id": subId }, // 从subAssemblies数组中移除_id匹配的元素 { $pull: { subAssemblies: { _id: subId } } } ); console.log(removeOne); res.json(removeOne); } catch (err) { res.send({ error: err }); } }
方案2:携带外层traveler文档id删除(推荐,查询效率更高)
- 先修改路由,增加外层文档id参数:
router.delete("/traveler/:travelerId/subassembly/:subId", deleteOneSubassembly);
- 修改控制器代码:
deleteOneSubassembly: async (req, res) => { try { const ObjectId = require('mongoose').Types.ObjectId; const travelerId = new ObjectId(req.params.travelerId); const subId = new ObjectId(req.params.subId); const removeOne = await Traveler.updateOne( // 先匹配外层文档id,缩小查询范围避免全表扫描 { _id: travelerId }, { $pull: { subAssemblies: { _id: subId } } } ); console.log(removeOne); res.json(removeOne); } catch (err) { res.send({ error: err }); } }
内容的提问来源于stack exchange,提问作者lhutchinson22
相关产品推荐
相关产品推荐

