Como alternar um campo booleano em um documento com operação atômica?
-
13-11-2019 - |
Pergunta
Existe alguma maneira de alternar o campo booleano de UM documento no MongoDB com operação atômica?Diga, (em python)
cl.update({"_id": ...}, {"$toggle": {"field": 1}})
Solução
No momento, não acho que seja possível fazer isso com uma operação.Os operadores bit a bit (http://www.mongodb.org/display/DOCS/Updating#Updating-%24bit) ainda não possuem um '$xor', embora eu tenha um patch para ele.
No momento, a solução alternativa que penso é sempre usar '$inc':
cl.update( { "_id": ...}, { '$inc' : { 'field' : 1 } } );
Então, em vez de verificar verdadeiro ou falso, você pode verificar se um item é "verdadeiro":
cl.find( { "_id": ..., 'field' : { '$mod' : [ 2, 1 ] } );
Ou seja, você está usando o operador módulo para ver se é par ou desigual, mesmo estando "desdefinido" e desigual sendo "definido".Se você deseja ter o comportamento oposto (ou seja, encontrar todos os itens que não possuem o sinalizador definido), use
[ 2, 0 ];
Outras dicas
O SERVIDOR-4362 o problema foi realmente resolvido agora e você tem a oportunidade $bit
operador de atualização disponível.Então, junto com isso xor
argumento, agora você pode fazer isso em uma ação atômica:
cl.findOneAndUpdate(
{ "_id": ...},
{
"$bit": {
"field": { "xor": NumberInt(1) }
}
},
{ "returnNewDocument": true, "upsert": true }
);
Portanto, desde que o valor do campo seja mantido em 0
ou 1
então, resultará uma "inversão" bit a bit que tornará o valor atual o oposto do que era no momento da modificação.
O .findOneAndUpdate()
não é obrigatório, mas apenas uma forma de demonstrar que o valor resultante é diferente a cada modificação.