MongoDB $cmp Operator

Beginner
⏱️ 9 min read
📚 Updated: Jul 2026
🎯 4 Examples
Comparison

What You’ll Learn

The $cmp operator compares two values and returns -1, 0, or 1 in MongoDB aggregation pipelines. It is the building block for multi-branch logic with $switch and custom ranking.

01

Three-Way Compare

Returns -1, 0, or 1.

02

Syntax

Two values in an array.

03

Any BSON Type

Numbers, strings, dates.

04

$switch

Power categorization logic.

05

Use Cases

Sort, rank, categorize.

06

vs $gt / $lt

When to use each.

Definition and Usage

In MongoDB’s aggregation framework, the $cmp operator compares two expressions and returns a numeric result: -1 if the first is less, 0 if equal, and 1 if the first is greater. For example, $cmp(85, 80) returns 1 because 85 is greater than 80.

💡
Beginner Tip

Think of $cmp like a three-way sign: less than, equal, or greater than. Pair it with $switch or $eq to turn comparison results into labels, tiers, or custom sort keys.

📝 Syntax

The $cmp operator takes two expressions in an array:

mongosh
{ $cmp: [ <expression1>, <expression2> ] }

Syntax Rules

  • $cmp — compares the first expression to the second.
  • Return values-1 (less), 0 (equal), 1 (greater).
  • Both expressions can be field references, literals, or nested expressions.
  • Comparison follows MongoDB BSON comparison order (Null < Numbers < Strings < Objects < Arrays).
  • Use inside stages like $project, $addFields, or $set.

💡 Return Value Cheat Sheet

$cmp: [ 75, 80 ]-1 (75 < 80)
$cmp: [ 80, 80 ]0 (equal)
$cmp: [ 90, 80 ]1 (90 > 80)
Check 1 for “greater than”, -1 for “less than”

⚡ Quick Reference

QuestionAnswer
Operator typeAggregation expression operator (comparison)
Syntax{ $cmp: [ expr1, expr2 ] }
Returns-1, 0, or 1
Greater than check{ $eq: [ { $cmp: [ a, b ] }, 1 ] }
Common stages$project, $addFields, $set
Greater
{
  $cmp: [ 90, 80 ]
}

Returns 1

Equal
{
  $cmp: [ 80, 80 ]
}

Returns 0

Less
{
  $cmp: [ 75, 80 ]
}

Returns -1

Fields
{
  $cmp: ["$a", "$b"]
}

Compare two fields

Examples Gallery

Compare student scores, assign performance labels with $switch, and compare two document fields.

📚 Compare Values

Use a students collection and see raw $cmp results with $project.

Sample Input Documents

Suppose you have a students collection with name and score fields:

mongosh
[
  { "_id": ObjectId("609c26812e9274a86871bc6a"), "name": "Alice",   "score": 85 },
  { "_id": ObjectId("609c26812e9274a86871bc6b"), "name": "Bob",     "score": 75 },
  { "_id": ObjectId("609c26812e9274a86871bc6c"), "name": "Charlie", "score": 90 }
]

Example 1 — Basic $cmp Against a Threshold

Compare each student’s score to the passing threshold of 80:

mongosh
db.students.aggregate([
  {
    $project: {
      name: 1,
      score: 1,
      vs80: { $cmp: [ "$score", 80 ] }
    }
  }
])

How It Works

  • Alice (85): cmp(85, 80)1 (above threshold).
  • Bob (75): cmp(75, 80)-1 (below threshold).
  • Charlie (90): cmp(90, 80)1 (above threshold).

📈 Practical Patterns

Turn comparison results into labels, tiers, and field-to-field checks.

Example 2 — Categorize with $switch and $cmp

Assign performance labels based on score thresholds (High ≥ 80, Medium ≥ 60, else Low):

mongosh
db.students.aggregate([
  {
    $project: {
      name: 1,
      score: 1,
      performance: {
        $switch: {
          branches: [
            {
              case: { $eq: [ { $cmp: [ "$score", 80 ] }, 1 ] },
              then: "High"
            },
            {
              case: { $eq: [ { $cmp: [ "$score", 60 ] }, 1 ] },
              then: "Medium"
            }
          ],
          default: "Low"
        }
      }
    }
  }
])

How It Works

$eq: [ { $cmp: [ "$score", 80 ] }, 1 ] is true when score strictly greater than 80. For scores exactly 80, use $gte instead, or add a branch for cmp === 0.

Example 3 — Compare Two Fields

Check whether actual inventory meets the expected level:

mongosh
db.inventory.aggregate([
  {
    $project: {
      item: 1,
      expected: 1,
      actual: 1,
      stockStatus: {
        $switch: {
          branches: [
            {
              case: { $eq: [ { $cmp: [ "$actual", "$expected" ] }, 1 ] },
              then: "Overstocked"
            },
            {
              case: { $eq: [ { $cmp: [ "$actual", "$expected" ] }, 0 ] },
              then: "Exact"
            }
          ],
          default: "Understocked"
        }
      }
    }
  }
])

How It Works

Comparing two fields with $cmp returns 1 when actual exceeds expected, 0 when they match, and -1 when actual is lower.

Example 4 — $cmp vs $gte (Simpler Alternative)

For a simple “passed or failed” check, $gte is often clearer than $cmp:

mongosh
db.students.aggregate([
  {
    $project: {
      name: 1,
      score: 1,
      // Using $cmp (returns -1, 0, or 1)
      cmpResult: { $cmp: [ "$score", 60 ] },
      // Using $gte (returns true or false) — simpler for pass/fail
      passed: { $gte: [ "$score", 60 ] }
    }
  }
])

// score: 75 → cmpResult: 1,  passed: true
// score: 60 → cmpResult: 0,  passed: true
// score: 45 → cmpResult: -1, passed: false

How It Works

Use $cmp when you need three outcomes. Use $gte, $gt, $lte, or $lt when you only need true/false.

🚀 Use Cases

  • Sorting logic — build custom sort keys based on relative value order.
  • Categorization — assign tiers or labels by comparing values against thresholds with $switch.
  • Ranking — compare scores or ratings to determine relative standing.
  • Data validation — compare actual vs expected fields and flag mismatches.

🧠 How $cmp Works

1

MongoDB evaluates both values

The pipeline resolves both expressions — fields like "$score" or literal thresholds.

Input
2

$cmp compares them

MongoDB applies BSON comparison rules and returns -1, 0, or 1.

Compare
3

The result drives downstream logic

Use the integer in $switch, $cond, or $eq to branch your pipeline.

Output
=

Actionable comparison data

Labels, ranks, and filters based on relative value order.

Conclusion

The $cmp operator is a flexible comparison tool in MongoDB aggregation pipelines. Its three-way return value (-1, 0, 1) makes it especially powerful inside $switch for categorization and ranking logic.

For beginners, remember: 1 means greater, -1 means less, 0 means equal. For simple pass/fail checks, $gte is often easier to read than $cmp.

💡 Best Practices

✅ Do

  • Use $cmp with $switch for multi-tier categorization
  • Remember 1 = greater, 0 = equal, -1 = less
  • Compare two fields when checking actual vs expected values
  • Use $gte when you only need a true/false result
  • Test edge cases: equal values and null inputs

❌ Don’t

  • Assume $cmp returns a boolean (it returns -1, 0, or 1)
  • Use cmp === 1 when you need “greater than or equal”
  • Compare values of incompatible BSON types without understanding order
  • Confuse $cmp with $eq (equality only)
  • Use $cmp as a query filter outside expressions

Key Takeaways

Knowledge Unlocked

Five things to remember about $cmp

Use these points when comparing values in MongoDB.

5
Core concepts
📝 02

Array Syntax

{ $cmp: [a, b] }

Syntax
📏 03

1 = Greater

First > second.

Rule
🛠 04

$switch Partner

Great for tiers.

Pattern
05

Not Boolean

Use $gte for true/false.

Important

❓ Frequently Asked Questions

$cmp compares two values and returns -1 if the first is less, 0 if equal, or 1 if the first is greater. It follows MongoDB BSON comparison order.
The syntax is { $cmp: [ <expression1>, <expression2> ] }. Both expressions can be field references, literals, or other expressions.
-1 means the first value is less than the second. 0 means they are equal. 1 means the first value is greater than the second.
Use $gt, $lt, $gte, and $lte for simple true/false checks. Use $cmp when you need a three-way result (-1, 0, 1) for $switch branches, sorting logic, or custom comparison handling.
If either argument is null, $cmp returns null unless both are null (which returns 0).

Continue the Operator Series

Move on to $comment for pipeline annotations, or review $and for logical expressions.

Next: $comment →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful