$mod is the modulo (remainder) operator. In aggregation it returns dividend % divisor. In queries it filters documents where a field’s remainder matches a value you choose—handy for “divisible by” and odd/even checks.
Pick compute (aggregation) or filter (query)—argument order differs.
To compute: use $addFields / $project with { $mod: [dividend, divisor] }.
To filter: use find() or $match with { field: { $mod: [divisor, remainder] } }.
Keep the divisor non-zero.
Remember: query array is not the same order as aggregation.
Context
Array order
Result
Aggregation
[dividend, divisor]
Returns the remainder
Query / $match
[divisor, remainder]
Keeps matching documents
Pseudocode
Pseudocode
// Aggregation — compute
for each document:
a = evaluate(dividend)
b = evaluate(divisor)
if a or b is null/missing:
result = null
else if b == 0:
error
else:
result = a % b
emit { ..., field: result }
// Query — filter
keep document if (field % divisor) == remainder
Reference
Cheat Sheet
Keep these facts handy while writing modulo expressions.
Topic
Detail
Agg syntax
{ $mod: [ <a>, <b> ] } → a % b
Query syntax
{ f: { $mod: [ <b>, <r> ] } } → f % b === r
Sample
80 % 7 = 3, 40 % 4 = 0
Even check
{ n: { $mod: [2, 0] } }
Odd check
{ n: { $mod: [2, 1] } }
Divide by zero
Pipeline / query error
Negative dividend
Remainder is negative
Try it
Live Preview
Watch aggregation $mod compute a remainder. Pick a pair, then run.
Simulates aggregation { $mod: [dividend, divisor] } (same idea as the mongosh examples below).
Array is [divisor, remainder].[4, 0] means “remainder must be 0”.
Matches.0 % 4 = 0 and 12 % 4 = 0.
Skipped.5 % 4 = 1, so item 2 is not returned.
Edge Cases & Pitfalls
Check these before using $mod in production pipelines.
order
Don’t mix argument orders
Aggregation is [dividend, divisor]. Query is [divisor, remainder]. Swapping them silently gives wrong results.
zero
Divisor must not be zero
A zero divisor errors. Guard with $cond or filter bad rows first.
sign
Negative dividends stay negative
-13 % 9 is -4, not 5. Plan for the sign if you store negatives.
null
Null inputs return null (aggregation)
If either argument is null or missing in aggregation, $mod returns null.
Analysis
Performance Notes
Approach
Cost
Best for
Agg $mod
Per-document math
Computed remainders / reports
Query $mod
Usually collection scan
Odd/even or divisible filters
Precompute + index
Faster reads
Hot remainder filters
Query $mod rarely uses a standard index efficiently. For frequent filters, store a helper field (for example qtyMod4) and index that, or narrow with $match on other fields first.
Remember
Key Takeaways
Agg:$mod([a, b]) → a % b.
Query:{ f: { $mod: [b, r] } } → f % b === r.
Order differs between compute and filter.
Never divide by zero.
One line:$mod answers “what is left after division?”—or “keep rows with this remainder.”
Frequently Asked Questions
In aggregation, $mod divides one number by another and returns the remainder (like % in JavaScript). In find() / $match queries, $mod filters documents where a field’s remainder equals a value you specify.
Use { field: { $mod: [ <divisor>, <remainder> ] } }. Example: { qty: { $mod: [ 4, 0 ] } } matches documents where qty % 4 === 0. The field is the dividend.
Aggregation $mod computes a value: [dividend, divisor]. Query $mod filters: [divisor, expected remainder] against the field. Check which context you are in before writing the array.
In aggregation, a zero divisor makes the pipeline fail. In queries, a zero divisor is invalid. Always use a non-zero divisor.
When the dividend is negative, the remainder is also negative (JavaScript-style). Example: $mod([-13, 9]) returns -4.