MongoDB Atomic Operations
MongoDB does not support multi-document ACID transactions. Therefore, you must design your application logic to handle data consistency without relying on the database for cross-document integrity. However, MongoDB provides a comprehensive set of atomic operations for single-document modifications. An atomic operation is one that is indivisible; it either completes entirely or not at all, prevanting partial updates.
Atomic Operation Data Model
Consider a data model for managing product inventory and sales. This example illustrates how embdeding related data within a single document ensures that updates to associated field are performed atomically.
product = {
itemId: "P1001",
name: "Wireless Mouse",
category: "Electronics",
inventory: {
stock: 50,
lastRestocked: ISODate("2023-10-26")
},
sales: [
{ quantity: 5, date: ISODate("2023-10-27") },
{ quantity: 3, date: ISODate("2023-10-28") }
]
}
You can use the db.collection.findOneAndUpdate() method (the modern equivalent of findAndModify) to check stock availability and record a new sale in a single, atomic operation. The embedded inventory.stock and sales fields are updated synchronously.
db.products.findOneAndUpdate(
{
itemId: "P1001",
"inventory.stock": { $gt: 0 }
},
{
$inc: { "inventory.stock": -1 },
$push: { sales: { quantity: 1, date: new Date() } }
}
)
Common Atomic Operation Commands
$set
Updates the value of a specified field. If the field does not exist, it is created.
{ $set: { "userProfile.lastLogin": new Date() } }
$unset
Removes a field from a document.
{ $unset: { "temporaryFlag": "" } }
$inc
Increments the value of a numeric field by a specified amount.
{ $inc: { "productInventory.stock": 10 } }
$push
Adds an item to an array. If the field is not an array, it will be created as one.
{ $push: { "orderHistory": { orderId: "ORD987", date: new Date() } } }
$pushAll
Adds multiple items to an array. (Note: This operator is deprecated in favor of using $each with $push in modern MongoDB versions.)
{ $pushAll: { "categories": ["new", "featured"] } }
$pull
Removes all array elements that match a specified condition.
{ $pull: { "members": { status: "inactive" } } }
$addToSet
Adds a value to an array only if it does not already exist in the array.
{ $addToSet: { "uniqueUsers": "user456" } }
$pop
Removes the first (specify -1) or last (specify 1) element of an array.
{ $pop: { "recentSearches": 1 } }
$rename
Renames a field.
{ $rename: { "oldAddress": "shippingAddress" } }
$bit
Performs a bitwise operation on a field with integer values.
{ $bit: { "flags": { and: 2 } } }
Positional Operator $
Used to update an element of an array that matches a condition.
// Find a document with a review by "john_doe" and increment that specific review's rating.
db.products.update(
{ "reviews.author": "john_doe" },
{ $inc: { "reviews.$.rating": 1 } }
)