Node.js操作MongoDB时$pull删除数组对象元素失效的解决方法
问题背景
现有MongoDB文档中tags字段的数据结构如下:
"tags": [{ "assigned_by": "XXXX", "tag": { "permissions": {"public": false, "roles": ["XXX","XXX"],"self": false}, "models": [ "COMMENTS"], "name": "IN_REVIEW", "created_at": {"$date": {"$numberLong": "1656396397488"}} }, "created_at": {"$date": {"$numberLong": "1656396444394"}} }]
需求为删除该对象数组的第0个元素。
此前尝试使用如下代码实现删除,但执行后目标标签未被成功删除:
editedComment.update( { _id: id }, { $pull: { 'comment.tags' : { 'tag': { name: 'IN_REVIEW' } } }})
失败原因
原有代码的$pull匹配条件写法错误:MongoDB对嵌套对象做全等匹配时,传入{ 'tag': { name: 'IN_REVIEW' } }会要求tag字段与传入对象完全一致,必须同时包含permissions、models、name、created_at所有字段且值完全匹配才能命中,仅传入name字段无法匹配到对应数组元素,因此删除操作不生效。
正确实现方式
根据实际场景二选一即可:
- 方案1:明确按数组索引删除第0位元素
兼容所有MongoDB版本的两步写法:
4.2及以上版本支持聚合更新管道,可一步完成:// 先将数组第0位元素置为null editedComment.update({ _id: id }, { $unset: { 'comment.tags.0': 1 } }) // 清除数组中所有null值,完成删除 editedComment.update({ _id: id }, { $pull: { 'comment.tags': null } })editedComment.update( { _id: id }, [ { $set: { 'comment.tags': { $slice: ['$comment.tags', 1, { $size: '$comment.tags' }] } } } ] ) - 方案2:按标签属性匹配删除所有
tag.name为IN_REVIEW的元素
使用点语法指定嵌套字段匹配规则,无需匹配整个tag对象:editedComment.update( { _id: id }, { $pull: { 'comment.tags': { 'tag.name': 'IN_REVIEW' } } } )
提示:如果
tags字段直接存在于文档根目录,没有嵌套在comment字段下,将上述代码中所有comment.tags替换为tags即可。
内容的提问来源于stack exchange,提问作者Shweta Dabgar
相关产品推荐
相关产品推荐

