使用 mongoose 从 Mongodb 中删除子文档
Posted
技术标签:
【中文标题】使用 mongoose 从 Mongodb 中删除子文档【英文标题】:Remove sub-document from Mongo with mongoose 【发布时间】:2013-09-04 10:12:12 【问题描述】:我正在尝试从存储在 mongoose 文档中的集合中删除一个项目。我的文档如下所示:
"__v": 3,
"_id": "5221040475f174d59a000005",
"items": [
"sku": 1321654654613213,
"name": "goldfish",
"quantity": 12,
"_id": "52224ed5bd9d340000000003"
,
"sku": 12,
"name": "goldfish",
"quantity": 13,
"_id": "52225dcbf2f1e40000000003"
,
"sku": 1299,
"name": "goldfish",
"quantity": 13,
"_id": "522260b6f2f1e40000000004"
]
我想删除sku为12的金鱼。我正在执行以下操作:
var inventory = res.locals.content;
inventory.items.remove( sku: req.params.itemSku, function (err, item)
if (err)
console.log('error occurred', err);
res.send('error');
else
res.send('Item found and deleted');
return;
);
当我这样做时,我收到错误“TypeError: Cannot read property 'equals' of undefined”。我不明白为什么。
【问题讨论】:
您提供的代码中没有出现equals
这个词。你能提供一个堆栈跟踪吗?
【参考方案1】:
子文档现在有一个remove 函数。从规范中使用如下:
var doc = parent.children.id(id).remove();
parent.save(function (err)
if (err) return handleError(err);
console.log('the sub-doc was removed')
);
【讨论】:
这是原子调用吗? 实际上,实际保存是原子的,我查看了源代码,它看起来像remove()
使用 MongooseArray.pull
,根据 v4 文档:Pulls items from the array atomically.
- 如果您担心数组索引不同步。话虽如此,您也可以使用MongooseArray.pull
来做同样的事情,就像接受的答案所述。
@OllyBarca 我确实做到了,因此“使用如下规范”。【参考方案2】:
您需要inventory.items.pull(req.params.itemSku)
,然后是inventory.save
呼叫。 .remove
用于***文档
【讨论】:
我在使用inventory.items.pull(sku: req.params.itemSku);
时没有收到任何错误,但这会返回整个数组而不是具有匹配 sku 的元素。这是为什么呢?
pull
返回this
,可能是为了可链接性,所以你可以这样做inventory.items.pull(blah).push(blah)
。 github.com/LearnBoost/mongoose/blob/…【参考方案3】:
从数组中删除子文档
我发现从 array 中查找和删除子文档的最好和最完整的解决方案是使用 Mongoose 的 $pull 方法:
Collection.findOneAndUpdate(
_id: yourCollectionId ,
$pull: subdocumentsArray: _id: subdocumentId ,
new: true ,
function(err)
if (err) console.log(err)
)
new: true
确保返回数据的更新版本,而不是旧数据。
【讨论】:
new: true 不确保现有文档被覆盖。它只返回更新数据的结果,而不是数据库中的旧数据。所以它的结果是子文档被删除。【参考方案4】:最后!
MongoDB:
"imgs" : "other" : [
"crop" : "../uploads/584251f58148e3150fa5c1a7/photo_2016-11-09_21-38-55.jpg",
"origin" : "../uploads/584251f58148e3150fa5c1a7/o-photo_2016-11-09_21-38-55.jpg",
"_id" : ObjectId("58433bdcf75adf27cb1e8608")
]
,
router.get('/obj/:id', function(req, res)
var id = req.params.id;
Model.findOne('imgs.other._id': id, function (err, result)
result.imgs.other.id(id).remove();
result.save();
);
【讨论】:
【参考方案5】:您可以简单地使用$pull 删除子文档。
Collection.update(
_id: parentDocumentId
,
$pull:
subDocument:
_id: SubDocumentId
);
这将根据给定 ID 找到您的父文档,然后从子文档中删除与给定条件匹配的元素。
【讨论】:
但为此我需要知道不需要的父 ID 和子文档 ID。【参考方案6】: const deleteitem = (req, res) =>
var id = req.body.id
var iditem = req.body.iditem
Venta.findOne('_id': id, function(err,result)
if (err)
console.log(err);
else
result.items.pull(iditem)
result.save()
)
module.exports = deleteitem
【讨论】:
以上是关于使用 mongoose 从 Mongodb 中删除子文档的主要内容,如果未能解决你的问题,请参考以下文章
NodeJs MongoDb Mongoose - 如何从多维数组中删除项目?
mongoose:使用$ pull删除嵌入式文档数组中的值(MongoDB 3.4版本)