Aggregation & Query Operators

Mongomock features a powerful, in-memory expression evaluation engine (mongomock/aggregate.py) designed to parse queries and run aggregation pipelines.

Supported Pipeline Stages

The following table lists the supported aggregation pipeline stages and their behavior:

Pipeline Stage Supported Options & Capabilities Behavioral Details
$match Full standard query syntax. Supports datetime and timezone normalization. Filters documents in-place using standard query filters.
$project Field inclusion/exclusion, subdocument filtering, and computed expressions. Generates new document shapes using calculated fields and variable mapping.
$addFields / $set Supports computed expressions, nested dot-notation paths, and object overrides. Appends new fields or updates existing fields in place.
$group Accumulators: $sum, $avg, $min, $max, $first, $last, $addToSet, $push, $mergeObjects. Groups documents by scalar or compound keys and applies accumulators.
$unwind Supports includeArrayIndex and preserveNullAndEmptyArrays. Splits array elements into individual documents.
$lookup Supports standard local/foreign field joining and custom let + pipeline subqueries. Performs left-outer joins against other in-memory collections.
$graphLookup Supports maxDepth, depthField, and restrictSearchWithMatch. Computes recursive hierarchical searches.
$bucket Supports boundaries and a default bucket option. Groups documents into specified value ranges.
$sample Supports size option. Selects random documents from the collection.
$facet Supports multiple parallel sub-pipelines. Runs multiple aggregations in parallel on the same document set.
$count Returns a count of documents passing through the stage. Outputs a single document with the count total.
$replaceRoot Promotes a nested subdocument to top-level state. Replaces the root document with a specified subdocument.

Supported Expression Operators

You can use the following operators within projections, field assignments, and logical checks:

Logic & Booleans

  • $and, $or, $not

Comparisons

  • $eq, $ne, $gt, $gte, $lt, $lte, $cmp

Math & Arithmetic

  • Unary: $abs, $ceil, $floor, $trunc, $sqrt, $exp, $ln, $log10
  • Multi-Key / Binary: $add, $subtract, $multiply, $divide, $mod, $pow, $log

String Formatting

  • $concat, $split, $substr, $toLower, $toUpper, $strcasecmp, $regexMatch

Conditionals & Control Flow

  • $cond, $ifNull, $switch

Array Manipulations

  • $concatArrays, $filter, $indexOfArray, $map, $slice, $size, $arrayElemAt

Type Verification & Conversions

  • $toString, $toInt, $toLong, $toDecimal, $arrayToObject, $objectToArray, $isNumber, $isArray

Example: Relational Join ($lookup)

This example joins a users collection with an orders collection in memory using $lookup:

import mongomock

db = mongomock.MongoClient().sales_database

# Seed user profiles
db.users.insert_many([
    {"_id": 1, "name": "Alice"},
    {"_id": 2, "name": "Bob"}
])

# Seed transaction records
db.orders.insert_many([
    {"_id": 101, "buyer_id": 1, "total": 250},
    {"_id": 102, "buyer_id": 1, "total": 45},
    {"_id": 103, "buyer_id": 3, "total": 80}
])

# Aggregate using a left-outer join
pipeline = [
    {
        "$lookup": {
            "from": "orders",
            "localField": "_id",
            "foreignField": "buyer_id",
            "as": "purchase_history"
        }
    },
    {"$sort": {"_id": 1}}
]

results = list(db.users.aggregate(pipeline))

# Verify results
assert results[0]["name"] == "Alice"
assert len(results[0]["purchase_history"]) == 2
assert results[1]["name"] == "Bob"
assert len(results[1]["purchase_history"]) == 0

For details on configuring database behaviors and handling unsupported options, see the Configuration Guide.