mongodb 从mongodb数组中的所有元素中删除一个字段
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19945924/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Remove a field from all elements in array in mongodb
提问by Nancy
I have below document in MongoDB(2.4.5)
我在 MongoDB(2.4.5) 中有以下文档
{
"_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"
}
I want to remove withBase filed from array elements inside casts.crew ..
我想从 casts.crew 内的数组元素中删除 withBase 文件。
I tried this
我试过这个
db.coll.update({_id:235399},{$unset: { "casts.crew.withBase" : 1 } },false,true)
nothing changed.
没有改变。
And tried this..
并尝试了这个..
db.coll.update({_id:235399},{$unset: { "casts.crew" : { $elemMatch: { "withBase": 1 } } } },false,true)
it removed entire crew array from the document.
它从文档中删除了整个乘员组。
Can someone please provide me the right query?
有人可以向我提供正确的查询吗?
回答by Sagar Veeram
You can use the new positional identifier
to update multiple elements in array in 3.6.
您可以使用 newpositional identifier
更新 3.6 中数组中的多个元素。
Something like
就像是
db.coll.update( {_id:235399}, {$unset: {"casts.crew.$[].withBase":""}} )
$[]removes all the withBase
property from the crews
array. It acts as a placeholder for updating all elements in array.
$[]withBase
从crews
数组中删除所有属性。它充当更新数组中所有元素的占位符。
Use multi true to affect multiple documents.
使用 multi true 来影响多个文档。
回答by Salvador Dali
Sorry to disappoint you, but your answer
抱歉让你失望了,但你的回答
db.coll.update({
_id:235399,
"casts.crew.withBase": {$exists: true}
},{
$unset: {
"casts.crew.$.withBase" : true
}
},false,true)
is not correct. Actually it will remove the value, BUT only from the first occurrence of the subdocument, because of the way positional operator works:
是不正确的。实际上,由于位置运算符的工作方式,它只会从子文档的第一次出现中删除该值:
the positional $ operator acts as a placeholder for the first element that matches the query document
位置 $ 运算符充当与查询文档匹配的第一个元素的占位符
You also can not use $unset
(as you tried before) because it can not work on arrays (and are you basically trying to remove a key from a document from the array). You also can not remove it with $pull
, because pull removes all the array, not just a field of it.
您也不能使用$unset
(如您之前尝试过的),因为它不能在数组上工作(并且您基本上是在尝试从数组中的文档中删除一个键)。您也不能使用 删除它$pull
,因为 pull 会删除所有数组,而不仅仅是它的一个字段。
Therefore as far as I know you can not do this with a simple operator. So the last resort is doing $find
and then forEach
with save. You can see how to do this in my answer here. In your case you need to have another loop in forEach
function to iterate through array and to delete a key. I hope that you will be able to modify it. If no, I will try to help you.
因此,据我所知,你不能用一个简单的操作符来做到这一点。所以最后的手段是做$find
然后forEach
用保存。你可以在我的回答中看到如何做到这一点。在您的情况下,您需要在forEach
函数中使用另一个循环来遍历数组并删除一个 key。我希望你能修改它。如果没有,我会尽力帮助你。
P.S. If someone looks a way to do this - here is Sandra's function
PS如果有人看起来有办法做到这一点 - 这是桑德拉的功能
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);
});
回答by Hassek
I found a way to unset this lists without having to pull up the object (meaning, just doing an update), it's pretty hackish but if you have a huge database it will make the deal:
我找到了一种无需拉出对象即可取消设置此列表的方法(意思是,只需进行更新),这很hackish,但如果您有一个庞大的数据库,它就会完成交易:
db.coll.update({},{$unset: {"casts.crew.0.withBase" : 1, "casts.crew.1.withBase" : 1} }, {multi: 1})
In other words, you have to calculate how many objects there can be in any of your documents list and add those numbers explicitly, in this case as {casts.crew.NUMBER.withBase: 1}
.
换句话说,您必须计算任何文档列表中可以有多少个对象,并明确添加这些数字,在这种情况下为{casts.crew.NUMBER.withBase: 1}
.
Also, to count the longest array in a mongodb object, an aggregate can be done, something like this:
此外,要计算 mongodb 对象中最长的数组,可以进行聚合,如下所示:
db.coll.aggregate( [ { $unwind : "$casts.crew" }, { $group : { _id : "$_id", len : { $sum : 1 } } }, { $sort : { len : -1 } }, { $limit : 1 } ], {allowDiskUse: true} )
Just want to emphasize that this is not a pretty solution but is way faster than fetching and saving.
只是想强调一下,这不是一个很好的解决方案,但比获取和保存要快得多。