$tanh is a MongoDB aggregation expression that returns the hyperbolic tangent of a number. The result always sits in (-1, 1)—useful for gently squashing scores. It is not the same as trigonometric $tan.
Remember
$tanh = Math.tanh for aggregation
{ $tanh: <expression> }
input → number (radians if you treat it as an angle)
output → value in (-1, 1)
null / missing → null
NaN → NaN
+Infinity → 1
-Infinity → -1
Use the result as a normalized score or feature value.
Piece
Required?
Role
$tanh
Yes
Hyperbolic tangent → (-1, 1)
Expression
Yes
Number, field, or nested math
$degreesToRadians
No
Only when the stored value is in degrees
Pseudocode
Pseudocode
for each document:
x = evaluate(expression)
if x is null or missing:
result = null
else if x is NaN:
result = NaN
else if x is +Infinity:
result = 1
else if x is -Infinity:
result = -1
else:
result = tanh(x) // in (-1, 1)
emit { ..., field: result }
Reference
Cheat Sheet
Keep these facts handy while writing hyperbolic-tangent expressions.
Topic
Detail
Type
Aggregation expression (not a find filter)
Syntax
{ $tanh: <expression> }
Output range
(-1, 1) for finite inputs
Sample check
tanh(0) = 0, tanh(1) ≈ 0.7616
Degrees pattern
{ $tanh: { $degreesToRadians: <deg> } }
vs $tan
Hyperbolic vs trigonometric—different math
Infinity
+∞ → 1, -∞ → -1
Try it
Live Preview
Watch $tanh squash a number into (-1, 1). Larger magnitudes move closer to the edges.
Simulates $tanh (same idea as the mongosh examples below).
Result
x = 1
$tanh → 0.761594
{ tanh: 0.761594 }
Trace
Worked Walkthrough — Squash a Score
Start with score x = 1. Hyperbolic tangent maps it into (-1, 1) without hard clipping.
We store one score, then apply $tanh. Example 3 shows the same idea with a degree-style value (like the MongoDB docs). Insert the sample data once in mongosh.
Example 1 — Sample Data
Imagine one numeric score 1 and one angle in degrees 0. We save both in a collection named hyperbolic.
Same pattern as official docs. Use this wrap whenever a degree field feeds $tanh.
Edge Cases & Pitfalls
Check these before using $tanh in production pipelines.
vs tan
Not the same as $tan
$tan is trigonometric and unbounded. $tanh is hyperbolic and stays in (-1, 1).
infinity
Infinity becomes ±1
+Infinity → 1 and -Infinity → -1. Unlike $tan, this does not throw.
null
Null and missing become null
Missing fields return null. Use $ifNull when you need a default.
inverse
Need the inverse? Use $atanh
$tanh goes number → (-1, 1). To reverse that, use $atanh (input must be in (-1, 1)).
Analysis
Performance Notes
Approach
Cost
Best for
$tanh alone
Per-document math
Scores already numeric
$degreesToRadians + $tanh
Still O(docs)
Degree-stored angle fields
Filter then $tanh
Fewer docs processed
Large collections
Hyperbolic math is cheap compared with large sorts or joins. Filter early with $match when only some documents need a squash.
Remember
Key Takeaways
Role: hyperbolic tangent → value in (-1, 1).
Not $tan: different function, different use cases.
Infinity:+∞ → 1, -∞ → -1.
Degrees: wrap with $degreesToRadians when needed.
One line:$tanh answers “squash this number into (-1, 1)”—smoothly, not with a hard clip.
Frequently Asked Questions
$tanh returns the hyperbolic tangent of a number. The result is always between -1 and 1. Use it inside aggregation expression stages such as $project and $addFields.
$tan is trigonometric tangent of an angle in radians (unbounded, periodic). $tanh is hyperbolic tangent of a real number (bounded in (-1, 1), S-shaped). They are different functions.
MongoDB documents $tanh as taking a numeric value measured in radians. If your field stores degrees, convert with $degreesToRadians first. For score-style numbers, pass the value directly.
Null or a missing field returns null. NaN returns NaN. Positive Infinity returns 1; negative Infinity returns -1.
Hyperbolic tangent gently squashes large positives toward 1 and large negatives toward -1, which is useful for normalizing scores in a pipeline.
Yes for the math. Think of $tanh as MongoDB’s aggregation version of Math.tanh—run it in the pipeline, not as a standalone find() filter.