MongoDB Atomic Operations
MongoDB does not support transactions, so when applying it in your project, be aware of this limitation. Regardless of the design, do not expect MongoDB to guarantee data integrity.
However, MongoDB provides many atomic operations, such as saving, modifying, and deleting documents, which are all atomic operations.
An atomic operation means that either the document is saved to MongoDB or it is not saved at all, without any intermediate state where the document is partially saved.
Atomic Operations Data Model
Consider the following example, which involves library books and checkout information.
The example demonstrates how to ensure that embedded fields related to atomic operations (e.g., update) are synchronized within the same document.
book = {
_id: 123456789,
title: "MongoDB: The Definitive Guide",
author: [ "Kristina Chodorow", "Mike Dirolf" ],
published_date: ISODate("2010-09-24"),
pages: 216,
language: "English",
publisher_id: "oreilly",
available: 3,
checkout: [ { by: "joe", date: ISODate("2012-10-15") } ]
}
You can use the db.collection.findAndModify()
method to check if a book is available for checkout and update the new checkout information.
Embedded fields available
and checkout
within the same document ensure that these fields are updated synchronously:
db.books.findAndModify({
query: {
_id: 123456789,
available: { $gt: 0 }
},
update: {
$inc: { available: -1 },
$push: { checkout: { by: "abc", date: new Date() } }
}
})
Common Atomic Operations Commands
$set
Used to specify a key and update its value, or create the key if it does not exist.
{ $set : { field : value } }
$unset
Used to delete a key.
{ $unset : { field : 1 } }
$inc
$inc
can increment or decrement a numeric field's value (only numeric values that meet the criteria).
{ $inc : { field : value } }
$push
Usage:
{ $push : { field : value } }
Appends value
to field
, which must be an array. If field
does not exist, it creates a new array.
$pushAll
Similar to $push
, but allows appending multiple values to an array field at once.
{ $pushAll : { field : value_array } }
$pull
Removes a value equal to _value
from the array field
.
{ $pull : { field : _value } }
$addToSet
Adds a value to an array only if the value is not already present.
$pop
Removes the first or last element of an array.
{ $pop : { field : 1 } }
$rename
Renames a field.
{ $rename : { old_field_name : new_field_name } }
$bit
Bitwise operations, for integer types.
{ $bit : { field : { and : 5 } } }
Positional Operator
> t.find() { "_id" : ObjectId("4b97e62bf1d8c7152c9ccb74"), "title" : "ABC", "comments" : [ { "by" : "joe", "votes" : 3 }, { "by" : "jane", "votes" : 7 } ] }
> t.update( { 'comments.by': 'joe' }, { $inc: { 'comments.$.votes': 1 } }, false, true )
t.find() { "_id" : ObjectId("4b97e62bf1d8c7152c9ccb74"), "title" : "ABC", "comments" : [ { "by" : "joe", "votes" : 4 }, { "by" : "jane", "votes" : 7 } ] }