Как переключить логическое поле в одном документе с атомарной операцией? - PullRequest
15 голосов
/ 27 февраля 2012

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

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

Ответы [ 2 ]

16 голосов
/ 27 февраля 2012

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

Сейчас я думаю, что обходной путь - это всегда использовать '$ inc':

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

Тогда вместо проверки на true или false вы можете проверить, является ли элемент «true»:

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

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

[ 2, 0 ];
5 голосов
/ 07 апреля 2016

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...