MongoDB updateOne无法更新文档:移除文件引用失败
MongoDB updateOne返回修改计数但未实际删除元素的问题
问题背景
要移除文档files字段下各子数组(section1、section2、section3、others)中的指定对象引用,执行updateOne后返回结果显示匹配并修改了1条文档,但实际目标元素没被删掉。
目标文档结构
{ "_id": "64a3268474aa29e72b40c521", "name": "Test", "description": "", "files": { "section1": [ { "$oid": "64e617006e14fecb803b8bb3" }, { "$oid": "64e5fba8742cefedd2897e9e" } ], "section2": [ { "$oid": "64e5fba8742cefedd2897e98" } ], "section3": [], "others": [] } }
待删除ID数组
[ ["64e5fba8742cefedd2897e9a", "64e5fba8742cefedd2897e9e"], ["64e5fba8742cefedd2897e98"], [], [] ]
执行的更新代码
await this.myModel.updateOne( { _id: id }, { $pull: { 'files.section1': { _id: { $in: filesToDeleteIds[0] }}, 'files.section2': { _id: { $in: filesToDeleteIds[1] }}, 'files.section3': { _id: { $in: filesToDeleteIds[2] }}, 'files.others': { _id: { $in: filesToDeleteIds[3] }}, }} )
执行结果
{ "acknowledged": true, "modifiedCount": 1, "upsertedId": null, "upsertedCount": 0, "matchedCount": 1 }
问题原因
你写的$pull匹配条件和文档里的元素结构不匹配:文档中子数组的元素是包含$oid字段的对象,但你用_id作为匹配键,MongoDB找不到符合条件的元素,自然删不掉。
解决方案
把$pull条件里的_id替换成$oid即可,或者转换成ObjectID类型进行匹配(更规范)。
修复后的代码
await this.myModel.updateOne( { _id: id }, { $pull: { 'files.section1': { $oid: { $in: filesToDeleteIds[0] }}, 'files.section2': { $oid: { $in: filesToDeleteIds[1] }}, 'files.section3': { $oid: { $in: filesToDeleteIds[2] }}, 'files.others': { $oid: { $in: filesToDeleteIds[3] }}, }} )
更严谨的写法(使用ObjectID类型)
如果你的ID是字符串格式,建议转换成MongoDB的ObjectID类型再匹配,避免类型不兼容问题:
const { ObjectId } = require('mongodb'); // 将待删除ID数组转换成ObjectID类型 const formattedDeleteIds = filesToDeleteIds.map(sectionIds => sectionIds.map(id => new ObjectId(id)) ); await this.myModel.updateOne( { _id: new ObjectId(id) }, { $pull: { 'files.section1': { $oid: { $in: formattedDeleteIds[0] }}, 'files.section2': { $oid: { $in: formattedDeleteIds[1] }}, 'files.section3': { $oid: { $in: formattedDeleteIds[2] }}, 'files.others': { $oid: { $in: formattedDeleteIds[3] }}, }} )
内容的提问来源于stack exchange,提问作者Илья Никитин
相关产品推荐
相关产品推荐

