【问题标题】:MongoDB update with conditionMongoDB 更新条件
【发布时间】:2016-08-10 11:05:10
【问题描述】:

我正在尝试根据条件更新集合中的某些字段。

如果条件为true,我想将字段active设置为true,否则设置为false

这是无条件更新

db.consent.update(
{}, //match all
{
    $set: {
        "active": true
    }
}, 
{
    multi: true,
}

)

我想像这样添加一个更新条件:

db.consent.update(
{},
$cond: {
    if: {

        $eq: ["_id", ObjectId("5714ce0a4514ef3ef68677fd")]

    },
    then: {
        $set: {
            "active": true
        }
    },
    else: {
        $set: {
            "active": false
        }
    }
}, 
{
    multi: true,
}

)

根据https://docs.mongodb.org/manual/reference/operator/update-field/,没有$cond 运算符可供更新。

我有哪些选项可以将这个更新作为单个命令执行?

【问题讨论】:

标签: mongodb database


【解决方案1】:

你不能。

Mongo 不支持在更新语句中组合字段、条件等。


请参阅下面的https://stackoverflow.com/a/56551655/442351

【讨论】:

  • 我不知道,只需要进行两次更新调用。一个为真,一个为假。
  • 仅供参考,您可以根据条件更新文档,但不能在查询中写入 if else。
【解决方案2】:

我们可以使用聚合管道来做到这一点。在这里,我将男性更新为女性,将女性更新为男性。

db.customer.updateMany(
   { },
   [
     { $set: { gender: { $switch: {
                           branches: [
                               { case: { $eq: [ "$gender", 'male' ] }, then: "female" },
                               { case: { $eq: [ "$gender", 'female' ] }, then: "male" }
                           ],
                           default: ""
     } } } }
   ]
)

【讨论】:

    【解决方案3】:
    db.consent.update(
        {
           //YOUR CONDITIONAL HERE TO APLLAY UPDATE ONLY IF CONDITIONAL HAPPEN, SO THE "active": true WILL BE APPLY. 
        }, 
        {
           $set: {
             "active": true,
             "active2": FALSE,
           }
        }, 
        {
            multi: true,
        }
    )
    

    【讨论】:

    • 这可能是一个很好的答案,但添加解释会对其他人有用
    【解决方案4】:

    Mongo 4.2开始,db.collection.update()可以接受一个聚合管道,最后允许基于另一个字段更新/创建一个字段:

    // { a: "Hello", b: "World" }
    // { a: "Olleh", b: "Dlrow" }
    db.collection.update(
      {},
      [ { $set: { active: { $eq: [ "$a", "Hello" ] } } } ],
      { multi: true }
    )
    // { a: "Hello", b: "World", active: true  }
    // { a: "Olleh", b: "Dlrow", active: false }
    
    • 第一部分{} 是匹配查询,过滤要更新的文档(在我们的例子中是所有文档)。

    • 第二部分[ { $set: { active: { $eq: [ "$a", "Hello" ] } } } ] 是更新聚合管道(注意方括号表示使用聚合管道)。 $set 是一个新的聚合运算符,别名为$addFields。然后可以在$set 阶段内使用任何聚合运算符;在我们的例子中,条件相等检查取决于用于新 active 字段的值。

    • 不要忘记{ multi: true },否则只会更新第一个匹配的文档。

    【讨论】:

      【解决方案5】:

      当然可以.... 通过运行 2 个查询

      db.collection.update({condition}, { $set: { state } }, { multi: true });
      db.collection.update({!condition}, { $set: { state } }, { multi: false });
      

      你的例子

      db.consent.update(
        {"_id": ObjectId("5714ce0a4514ef3ef68677fd")},
        { $set: { "active": true } });
      
      db.consent.update(
        {"_id": {$ne: ObjectId("5714ce0a4514ef3ef68677fd")}},
        { $set: { "active": false } },
        { multi: true });
      

      【讨论】:

      • 这里的multi 选项用于将修饰符应用于多个匹配记录,而不是$set 值。如果您只想更新第一条匹配记录,请将multi 设置为false(默认),否则,将multi 明确提及为true 以更新所有记录。
      【解决方案6】:

      如果您有 MongoDB 版本 3.2+,您可以使用 findAndModify()findOneAndUpdate() 有条件地更新 MongoDB 文档

      【讨论】:

      • 来自文档 The findAndModify command modifies and returns a single document 。所以这仅适用于一个文档,但我需要更新整个集合。所以我认为我基本上坚持:1)两阶段提交 2)2 个查询 3)其他一些文件,其中包含有关此文件的信息 4)更改实现
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-15
      • 2013-10-16
      • 1970-01-01
      • 2017-10-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多