在Mongoose中如何查询schema内的嵌套数组并删除指定元素
你第一种写法的逻辑本身没有问题,不生效通常是两个常见原因导致的:
- 类型不匹配:从
req.body中获取的itemId是字符串类型,而MongoDB默认存储的文档/子文档_id为ObjectId类型,两者类型不一致导致$pull无法匹配到对应的子文档。 - 异步操作未等待:
updateOne是异步方法,如果没有加await也没有传入回调函数,程序不会等待操作执行完成,会出现操作未生效的假象。
正确实现代码
异步/await写法(推荐)
const mongoose = require('mongoose'); const listId = req.body.listId; const itemId = req.body.itemId; // 执行更新操作,await等待执行完成 const updateResult = await List.updateOne( { _id: listId }, { $pull: { items: { _id: mongoose.Types.ObjectId(itemId) } } } ); // 可以通过modifiedCount判断是否操作成功 // updateResult.modifiedCount === 1 代表修改成功
回调写法
const mongoose = require('mongoose'); const listId = req.body.listId; const itemId = req.body.itemId; List.updateOne( { _id: listId }, { $pull: { items: { _id: mongoose.Types.ObjectId(itemId) } } }, (err, result) => { if (err) return console.log(err); // result.modifiedCount 判断操作结果 } );
补充说明
如果你的cardSchema中自定义了_id的类型为字符串,不需要做类型转换,此时可以通过返回结果的matchedCount和modifiedCount排查问题:
matchedCount === 0:未找到对应listId的文档matchedCount === 1但modifiedCount === 0:找到对应list,但数组中没有匹配itemId的元素
内容的提问来源于stack exchange,提问作者purpleovskoff
相关产品推荐
相关产品推荐

