Remove a field from all elements in array in mongodb
我有以下MongoDB文档(2.4.5)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | { "_id" : 235399, "casts" : { "crew" : [ { "_id" : 1186343, "withBase" : true, "department" :"Directing", "job" :"Director", "name" :"Connie Rasinski" }, { "_id" : 86342, "withBase" : true } ] }, "likes" : 0, "rating" : 0, "rating_count" : 0, "release_date" :"1955-11-11" } |
我想从casts.crew中的数组元素中删除withbase文件。
我试过这个
1 | db.coll.update({_id:235399},{$unset: { "casts.crew.withBase" : 1 } },false,true) |
没有改变。
尝试过这个……
1 | db.coll.update({_id:235399},{$unset: { "casts.crew" : { $elemMatch: {"withBase": 1 } } } },false,true) |
它从文档中删除了整个地震队阵列。
有人能为我提供正确的查询吗?
很抱歉让你失望,但是你的回答
1 2 3 4 5 6 7 8 | db.coll.update({ _id:235399, "casts.crew.withBase": {$exists: true} },{ $unset: { "casts.crew.$.withBase" : true } },false,true) |
不正确。实际上,由于位置运算符的工作方式,它将移除该值,但仅从子文档的第一个出现处移除:
the positional $ operator acts as a placeholder for the first element
that matches the query document
您也不能使用
因此,据我所知,你不能用一个简单的算符来做这个。因此,最后一个办法是先实施
另外,如果有人想办法做到这一点,这是桑德拉的功用
1 2 3 4 5 6 7 8 | db.coll.find({_id:235399}).forEach( function(doc) { var arr = doc.casts.crew; var length = arr.length; for (var i = 0; i < length; i++) { delete arr[i]["withBase"]; } db.coll.save(doc); }); |
您可以使用新的
类似的东西
1 | db.coll.update( {_id:235399}, {$unset: {"casts.crew.$[].withBase":""}} ) |
$[]从
使用multi-true可影响多个文档。
我发现了一种不用拉上对象就可以取消设置列表的方法(也就是说,只需进行一次更新),这非常简单,但是如果你有一个庞大的数据库,它将完成交易:
1 | db.coll.update({},{$unset: {"casts.crew.0.withBase" : 1,"casts.crew.1.withBase" : 1} }, {multi: 1}) |
换句话说,您必须计算任何文档列表中可以有多少个对象,并明确地添加这些数字,在本例中为
此外,要计算MongoDB对象中最长的数组,可以进行聚合,如下所示:
1 | db.coll.aggregate( [ { $unwind :"$casts.crew" }, { $group : { _id :"$_id", len : { $sum : 1 } } }, { $sort : { len : -1 } }, { $limit : 1 } ], {allowDiskUse: true} ) |
只是想强调一下,这不是一个很好的解决方案,但比提取和保存要快得多。