如何使用原子操作在一个文档中切换布尔字段?

时间:2012-02-27 03:45:34

标签: mongodb mongodb-query

有没有办法通过原子操作切换MongoDB中ONE文档的布尔字段?说,(在python中)

cl.update({"_id": ...}, {"$toggle": {"field": 1}})

3 个答案:

答案 0 :(得分:16)

现在,我不认为通过一次操作可以做到这一点。位运算符(http://www.mongodb.org/display/DOCS/Updating#Updating-%24bit)没有'$ xor',尽管我有一个补丁。

现在我想到的解决方法是始终使用'$ inc':

cl.update( { "_id": ...}, { '$inc' : { 'field' : 1 } } );

然后,您可以检查项目是否为“true”,而不是检查是否为真:

cl.find( { "_id": ..., 'field' : { '$mod' : [ 2, 1 ] } );

IE,你使用模运算符来查看它是偶数还是不均匀,即使是“未设置”,也不均衡是“设置”。如果你想拥有相反的行为(即找到没有设置标志的所有项目),那么使用

[ 2, 0 ];

答案 1 :(得分:5)

SERVER-4362问题现在已经解决,您可以使用$bit更新运算符。因此,除了它的xor参数之外,您现在可以在原子操作中执行此操作:

cl.findOneAndUpdate( 
  { "_id": ...}, 
  { 
     "$bit": { 
         "field": { "xor": NumberInt(1) } 
     } 
  },
  { "returnNewDocument": true, "upsert": true }
);

因此,只要字段的值保持在01,就会产生按位“翻转”,使得当前值与修改时的值相反

.findOneAndUpdate()不是必需的,但只是一种证明每次修改后结果值都不同的方法。

答案 2 :(得分:2)

您可以从 MongoDB v4.2 开始使用 update with aggregation pipeline

1) 选项使用 $not

  • 计算一个布尔值并返回相反的布尔值;即当传递一个评估为真的表达式时,$not 返回假;当传递计算结果为 false 的表达式时,$not 返回 true。
cl.update(
  {"_id": ...}, 
  [
    { "$set": { "field": { "$not": "$field" } } }
  ]
)

Playground

<块引用>

$not 的缺点如下评估为假:null、0 和未定义的值以及其他值为真!

2) 使用 $eq

的选项
  • 如果字段为 false,则将字段设置为 true,如果它是任何其他值,则设置为 false。
cl.update(
  {"_id": ...}, 
  [
    { "$set": { "field": { "$eq": [false, "$field"] } } }
  ]
)

Playground