2012-02-27 7 views
13

¿Hay alguna forma de alternar el campo booleano de UN documento en MongoDB con operación atómica? Diga, (En python)¿Cómo se alterna un campo booleano en un documento con operación atómica?

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

Las operaciones en un documento separado son atómicas, pero las operaciones en un conjunto de documentos no son atómicas. ¿Quiere decir que necesita cambiar la bandera de todos los documentos de la colección? – Oleg

+0

Lo siento, no dejé esto en claro. Me gustaría operaciones en documento separado. – halfjuice

Respuesta

15

En este momento, no creo que sea posible hacerlo con una sola operación. Los operadores bit a bit (http://www.mongodb.org/display/DOCS/Updating#Updating-%24bit) aún no tienen '$ xor' aunque tengo un parche para ello.

En este momento la solución creo que ocurre es usando siempre '$ inc':

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

Entonces, en lugar de la comprobación de verdadero o falso, puede hacerlo y comprueba si un elemento es "verdadero":

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

IE, usted está usando el operador de módulo para ver si es par o desigual incluso si está "desarmado" y si está "desalineado". Si usted quiere tener el comportamiento oppposite (es decir, encontrar todos los artículos que no tienen establecido el indicador), a continuación, utilizar

[ 2, 0 ];

+0

Buena solución, propuesta similar en #mongodb;) Entrada como resultado de esa conversación aquí https://jira.mongodb.org/browse/SERVER-4362 –

4

La cuestión es en realidad SERVER-4362 resuelto ahora y que tiene el operador $bit actualización disponible. Así que junto con su xor argumento ahora se puede hacer esto en una acción atómica:

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

Así que, mientras el valor del campo se mantiene a 0 o 1 a continuación, un bit a bit "flip" dará como resultado que hace que el valor actual lo contrario de lo que era en el momento de la modificación.

No se requiere el .findOneAndUpdate(), sino simplemente una forma de demostrar que el valor resultante es diferente en cada modificación.

+4

¿Hay alguna forma de usar esto para valores booleanos en lugar de enteros? – mlovic

Cuestiones relacionadas