我试图取消设置嵌入在数组中的文档中的所有值。假设我有一个数组coll
的集合things
,其中包含值myval
。我想取消myval
。这看起来像:
{ things: [{ myval: 1 }, { myval: 2 }] }
我试过了两次
db.coll.update({}, {$unset: {'things.myval': 1}})
和
db.coll.things.update({}, {$unset: {'myval': 1}})
这些都不奏效。我在网上找不到任何描述如何执行此操作的文档。
答案 0 :(得分:1)
您可以使用 $ pull 运算符从“数组”中删除值:
db.coll.update({}, {$pull: {'things': {'myval': 1}}});
另请查看 $ pull 的文档:
http://www.mongodb.org/display/DOCS/Updating#Updating-%24pull
答案 1 :(得分:1)
根据官方文档应该使用您的第一种方法:
db.coll.update({}, {$unset: {'things.myval': 1}})
但这对我不起作用。因此,我发现的解决方案适用于您的示例:
db.coll.find().forEach(function(o) {
for(var i=0; i<o.things.length; i++) {
var unset = {};
unset["things." + i + ".myval"] = "";
db.coll.update( { "_id": o._id }, { "$unset": unset } );
}
})
或者更具功能性的风格:
db.coll.find().forEach(function(o) {
o.things.forEach(function(t, i) {
var unset = {};
unset["things." + i + ".myval"] = "";
db.coll.update( { "_id": o._id }, { "$unset": unset } );
})
})
答案 2 :(得分:1)
我遇到了这个问题,很沮丧地发现唯一的办法就是使用嵌套的forEach。因此,经过一番搜索,我发现了另一种方法!从mongo 3.6版开始,有一个all positional operator($[]
)(在问了这个问题之后引入了3.6版...甚至在上次激活之后,也要万一其他人遇到此问题)< / p>
要从要匹配的第一个嵌入式文档中删除列myval
,请执行以下操作:
db.coll.update(
{things: {'$exists': true}},
{$unset: {'things.$[].myval': 1}}
)
或者如果您想从所有匹配的文档中删除它,请使用updateMany
db.coll.updateMany(
{things: {'$exists': true}},
{$unset: {'things.$[].myval': 1}}
)
$unset
仅在值存在的情况下对其进行编辑,但不会进行安全导航(即,它不会首先检查其是否存在),因此嵌入式文档/数组上需要存在该值。
答案 3 :(得分:-1)
它无法工作,因为{} -empty选择器选择多个文档,并且正常更新会尝试更新单个文档。为了使其工作,请使用multi标志告诉mongo更新不止一个文件来了。
multi - 表示是否应更新所有符合条件的文档 而不仅仅是一个。对于下面的$运算符非常有用。
db.coll.update({}, {$unset: {'things.myval': 1}},false,true)
或
db.coll.update({}, {$pull: {'things': {'myval': 1}}},false,true)
尝试其中任何一个并且会看到哪个有效,但你必须在两个
中使用多个参数