Usage Guide
This guide covers the core CRUD operations, document update patterns, and reference options supported by Mongomock's database and collection APIs.
Document Insertion & ID Management
When inserting documents, Mongomock automatically manages unique identifiers, BSON typing, and basic validation rules:
- Automatic ID Assignment: If an insertion payload lacks an
_idfield, Mongomock generates and inserts a uniquebson.objectid.ObjectId(or a simulated fallback) directly into the document copy. - Key Constraint Enforcement: Top-level document keys must be strings. Attempting to insert keys of other types (like integers or booleans) raises a
ValueErrororInvalidDocumentexception. - No Duplicate IDs: Attempting to insert a document with an
_idthat already exists in the collection raises aDuplicateKeyError.
import mongomock
client = mongomock.MongoClient()
collection = client.ecommerce.products
# Success: Automatically appends an '_id'
item_id = collection.insert_one({"sku": "A-001", "price": 19.99}).inserted_id
# Raises DuplicateKeyError: Duplicate ID
try:
collection.insert_one({"_id": item_id, "sku": "A-002"})
except mongomock.DuplicateKeyError as err:
print(f"Insertion rejected: {err}")
Advanced Querying & Filtering
Mongomock supports MongoDB's query language, including subdocument filters, comparison operators, and array matching.
Subdocument Dot Notation
You can query nested values using dot-notation fields. Mongomock parses these dotted strings and traverses the document dictionary structure dynamically:
collection.insert_one({
"sku": "M-404",
"specs": {"dimensions": {"weight": 12, "unit": "kg"}}
})
# Query nested values
result = collection.find_one({"specs.dimensions.weight": {"$gt": 10}})
assert result["sku"] == "M-404"
Array Element Matching ($elemMatch)
Use $elemMatch to query documents containing array fields where at least one array element meets all specified filter criteria:
collection.insert_one({
"sku": "P-200",
"variants": [
{"color": "red", "size": "S"},
{"color": "blue", "size": "L"}
]
})
# Matches: One variant is both 'red' and 'S'
matching_item = collection.find_one({
"variants": {"$elemMatch": {"color": "red", "size": "S"}}
})
assert matching_item is not None
Document Update Operators
You can modify existing documents using update_one or update_many. Updates support a wide range of atomic operators.
Field Modifications ($set, $unset, $inc, $max, $min)
# Increment stock and update description
collection.update_one(
{"sku": "M-404"},
{
"$inc": {"stock": 5},
"$set": {"status": "in-stock"},
"$unset": {"discontinued": ""}
}
)
Array Modifiers ($push, $pull, $pop)
You can modify arrays using positional indicators ($) and modifiers like $each, $slice, $position, and $sort:
# Seed an array
collection.insert_one({"_id": "arr_doc", "prices": [10, 20, 30]})
# Push multiple elements and trim the array to the last 4 items
collection.update_one(
{"_id": "arr_doc"},
{
"$push": {
"prices": {
"$each": [40, 50, 60],
"$slice": -4
}
}
}
)
# Resulting array: [30, 40, 50, 60]
updated = collection.find_one({"_id": "arr_doc"})
assert updated["prices"] == [30, 40, 50, 60]
Atomic Find and Modify Operations
Mongomock supports atomic database transitions, allowing you to update a document and retrieve either its original or updated state using ReturnDocument:
from mongomock import ReturnDocument
# Increment a sequence and return the updated document state
sequence_doc = client.counters.ids.find_one_and_update(
{"_id": "transaction_id"},
{"$inc": {"seq": 1}},
upsert=True,
return_document=ReturnDocument.AFTER
)
print(f"Next transactional identifier: {sequence_doc['seq']}")
DBRefs & Reference Resolving
You can store logical relationships between collections using Database References (DBRef) and resolve them using Database.dereference():
from bson import DBRef
db = client.inventory_control
# 1. Insert product
laptop_id = db.products.insert_one({"model": "Latitude", "stock": 14}).inserted_id
# 2. Store DBRef in a separate collection
db.orders.insert_one({"order_no": 991, "product_ref": DBRef("products", laptop_id)})
# 3. Retrieve and resolve database reference
order_doc = db.orders.find_one({"order_no": 991})
product_doc = db.dereference(order_doc["product_ref"])
assert product_doc["model"] == "Latitude"
assert product_doc["stock"] == 14
To learn more about intercepting client connections and routing database calls, check out the Patching Guide.