NodeJS操作MongoDB删除嵌套数组对象代码无效果问题
MongoDB $pull 删除数组元素不生效的解决方法
你的代码失效是两个常见错误导致的:
- API用法错误:
updateOne()本身的逻辑就是仅更新符合筛选条件的第一条文档,你传入的{ multi: true }是早期update()方法的参数,updateOne和updateMany都不识别这个参数,传了也不会生效。如果要对所有匹配dcm条件的文档执行删除操作,需要替换为updateMany();如果只需要操作单条文档,直接删掉这个无效参数即可。另外upsert: false本来就是默认配置,不需要额外传。 - 类型不匹配问题:从你贴的存储数据来看,根节点的
dcm、comments数组内的id都是数字类型,如果你的入参comments.dcm、comments.id是从请求参数等位置拿到的字符串类型,会因为BSON类型严格匹配的规则,无法命中对应文档和数组元素,最终$pull不会执行任何操作。
前置排查
先执行查询确认筛选条件能命中目标文档,排除条件写错的问题:
// 注意传入的值类型要和库内一致,数字就不要加引号传字符串 const checkResult = await db.collection('status').find({ "dcm": comments.dcm, "comments.id": comments.id }).toArray() // 如果打印长度为0,说明你的筛选条件本身就匹配不到数据,先调整条件再做更新 console.log('命中文档数:', checkResult.length)
修正后的可用代码
仅更新第一条匹配的文档:
const deleteResult = await db.collection('status').updateOne( { "dcm": comments.dcm }, { $pull: { "comments": { "id": comments.id } } } ); // modifiedCount为1就代表删除成功,为0就是没有匹配到可修改的内容 console.log('修改的文档数:', deleteResult.modifiedCount)
需要更新所有匹配dcm条件的文档时,替换为updateMany即可:
const deleteResult = await db.collection('status').updateMany( { "dcm": comments.dcm }, { $pull: { "comments": { "id": comments.id } } } );
注意:
$pull会删除数组内所有符合条件的元素,你示例数据里两个comment的id都是289733,执行后两个元素都会被移除。如果只需要删除第一个匹配的元素,不要用$pull,要结合数组位置下标用$unset和$pop组合实现。
内容的提问来源于stack exchange,提问作者Nathan Field
相关产品推荐
相关产品推荐

