Подтвердить что ты не робот

Как переключить логическое поле в одном документе с атомной операцией?

Есть ли способ переключить логическое поле ОДНОГО документа в MongoDB с атомной операцией? Скажем, (в python)

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

Ответ 1

Прямо сейчас, я не думаю, что это возможно сделать с одной операцией. Побитовые операторы (http://www.mongodb.org/display/DOCS/Updating#Updating-%24bit) не имеют "$ xor", хотя у меня есть патч для него.

В настоящее время обходной путь, о котором я думаю, заключается в том, что всегда использует "$ inc":

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

Затем вместо проверки true или false вы можете проверить, является ли элемент "истинным":

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

IE, вы используете оператор modulo, чтобы убедиться, что он четный или неравномерный, даже будучи "неустановленным", и неравномерно "установлен". Если вы хотите иметь oppposite-поведение (т.е. Найти все элементы, которые не имеют установленного флага), используйте

[ 2, 0 ];

Ответ 2

Проблема SERVER-4362 действительно разрешена сейчас, и у вас есть $bit доступен оператор обновления. Итак, вместе с ним xor аргумент вы можете сделать это в атомном действии:

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

Итак, до тех пор, пока значение поля сохраняется в 0 или 1, тогда побитовое "флип" приведет к тому, что текущее значение будет противоположно тому, что было во время модификации.

.findOneAndUpdate() не требуется, а просто способ продемонстрировать, что результирующее значение отличается от каждой модификации.