如何在MongoDB中更新/设置/取消设置嵌入式文档/数组中的密钥?

时间:2011-10-13 18:48:00

标签: mongodb

我试图取消设置嵌入在数组中的文档中的所有值。假设我有一个数组coll的集合things,其中包含值myval。我想取消myval。这看起来像:

{ things: [{ myval: 1 }, { myval: 2 }] }

我试过了两次

db.coll.update({}, {$unset: {'things.myval': 1}})

db.coll.things.update({}, {$unset: {'myval': 1}})

这些都不奏效。我在网上找不到任何描述如何执行此操作的文档。

4 个答案:

答案 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)

尝试其中任何一个并且会看到哪个有效,但你必须在两个

中使用多个参数