18

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

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

3 回答 3

17

现在,我认为不可能通过一次手术来做到这一点。位运算符(http://www.mongodb.org/display/DOCS/Updating#Updating-%24bit)还没有'$xor',虽然我有一个补丁。

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

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

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

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

IE,您使用模运算符来查看它是均匀还是不均匀,甚至是“未设置”,不均匀是“设置”。如果你想有相反的行为(即,找到所有没有设置标志的项目),然后使用

[2, 0];

于 2012-02-27T10:01:24.017 回答
9

SERVER-4362问题现在实际上已解决,并且您可以使用更新$bit运算符。因此,除了它的xor论点,您现在可以在原子操作中执行此操作:

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

因此,只要字段的值保持在01之后,就会导致按位“翻转”,从而使当前值与修改时的值相反。

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

于 2016-04-07T01:16:11.283 回答
3

从 MongoDB v4.2 开始,您可以将更新与聚合管道一起使用,

1) 使用$not的选项

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

操场

缺点$not如下:null、0、未定义值和其他值都为真!

2) 使用$eq的选项

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

操场

于 2021-04-03T15:36:42.620 回答