Как переключить логическое поле в одном документе с атомной операцией?
Есть ли способ переключить логическое поле ОДНОГО документа в MongoDB с атомной операцией? Скажем, (в python)
cl.update({"_id": ...}, {"$toggle": {"field": 1}})
Ответы
Ответ 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()
не требуется, а просто способ продемонстрировать, что результирующее значение отличается от каждой модификации.