MongoDB $strcasecmp Operator

Beginner
⏱️ 8 min read
📚 Updated: Jul 2026
🎯 4 Examples
String Operations

What You’ll Learn

The $strcasecmp operator compares two strings without regard to letter case. It returns 0 when they match, -1 when the first is less, and 1 when the first is greater — ideal for case-insensitive filtering and validation.

01

Case-Insensitive

Ignore A vs a.

02

Return Values

0, -1, or 1.

03

Syntax

[ string1, string2 ].

04

$expr Queries

Filter in find().

05

Use Cases

Roles, status, emails.

06

vs $eq

Case-sensitive compare.

Definition and Usage

In MongoDB’s aggregation framework, the $strcasecmp operator performs a case-insensitive comparison of two strings. For example, { $strcasecmp: [ "Active", "active" ] } returns 0 because the strings are equal when case is ignored.

Use it when user input or stored data may vary in capitalization — such as status fields ("Pending" vs "pending"), role names, or email local parts. Pair it with $eq to test equality, or with $cond for conditional logic.

💡
Beginner Tip

Think of $strcasecmp like JavaScript’s localeCompare with case ignored, but it returns numeric 0, -1, or 1 instead of a boolean.

📝 Syntax

The $strcasecmp operator takes an array of two string expressions:

mongosh
{ $strcasecmp: [ <string1>, <string2> ] }

Return Values

mongosh
{ $strcasecmp: [ "Active", "active" ] }
// Result: 0  (equal, case ignored)

{ $strcasecmp: [ "apple", "banana" ] }
// Result: -1  (apple comes before banana)

{ $strcasecmp: [ "zebra", "apple" ] }
// Result: 1   (zebra comes after apple)

Syntax Rules

  • First argument — string expression (field path or literal).
  • Second argument — string expression to compare against.
  • Returns 0 — strings are equal (case-insensitive).
  • Returns -1 — first string is lexicographically less.
  • Returns 1 — first string is lexicographically greater.
  • Use inside $project, $addFields, $match with $expr, or find queries with $expr.

💡 $strcasecmp vs Case-Sensitive $eq

$strcasecmp — ignores case: "Admin" equals "admin"0
$eq — exact match: { $eq: [ "Admin", "admin" ] }false
Equality check: { $eq: [ { $strcasecmp: [ "$role", "admin" ] }, 0 ] }

⚡ Quick Reference

QuestionAnswer
Operator typeAggregation expression operator (string)
Syntax{ $strcasecmp: [ string1, string2 ] }
Equal stringsReturns 0
First less than secondReturns -1
First greater than secondReturns 1
Common stages$project, $match + $expr, find + $expr
Equal check
{
  $eq: [
    { $strcasecmp: ["$status", "active"] },
    0
  ]
}

Case-insensitive match

Compare fields
{
  $strcasecmp: ["$a", "$b"]
}

Two field paths

Literals
{
  $strcasecmp: ["Admin", "admin"]
}

Returns 0

In $match
$expr: { $eq: [...] }

Filter documents

Examples Gallery

Compare strings in aggregation pipelines, filter documents case-insensitively, and build conditional logic from comparison results.

📚 Basic Comparisons

Start with simple case-insensitive string comparisons in a $project stage.

Sample Input Documents

Suppose you have a users collection with mixed-case status values:

mongosh
[
  { "_id": 1, "name": "Alice", "status": "Active" },
  { "_id": 2, "name": "Bob",   "status": "inactive" },
  { "_id": 3, "name": "Carol", "status": "ACTIVE" },
  { "_id": 4, "name": "Dave",  "status": "Pending" }
]

Example 1 — Basic $strcasecmp Comparison

Compare each user’s status to the literal "active" (lowercase):

mongosh
db.users.aggregate([
  {
    $project: {
      name: 1,
      status: 1,
      compareResult: {
        $strcasecmp: [ "$status", "active" ]
      }
    }
  }
])

How It Works

0 means the strings are equal when case is ignored. Non-zero values indicate ordering, not just inequality.

📈 Filtering and Conditions

Use comparison results to filter documents and build boolean flags.

Example 2 — Filter Active Users with $match

Keep only documents whose status equals "active", regardless of case:

mongosh
db.users.aggregate([
  {
    $match: {
      $expr: {
        $eq: [
          { $strcasecmp: [ "$status", "active" ] },
          0
        ]
      }
    }
  },
  {
    $project: { name: 1, status: 1 }
  }
])

// Matches: Alice ("Active"), Carol ("ACTIVE")
// Excludes: Bob ("inactive"), Dave ("Pending")

How It Works

Wrap $strcasecmp in $eq ... 0 inside $expr. The $match stage then filters case-insensitively.

Example 3 — Case-Insensitive Find Query

Use the same pattern in a standard find() query:

mongosh
db.users.find({
  $expr: {
    $eq: [
      { $strcasecmp: [ "$role", "admin" ] },
      0
    ]
  }
})

// Matches role: "admin", "Admin", "ADMIN", etc.

How It Works

$expr lets aggregation expressions run inside find filters. This avoids storing duplicate lowercase copies of every string field.

Example 4 — Boolean Flag with $cond

Add an isActive field based on a case-insensitive status check:

mongosh
db.users.aggregate([
  {
    $addFields: {
      isActive: {
        $eq: [
          { $strcasecmp: [ "$status", "active" ] },
          0
        ]
      }
    }
  }
])

// "Active"  → isActive: true
// "ACTIVE"  → isActive: true
// "Pending" → isActive: false

How It Works

$eq with $strcasecmp produces a boolean. Use it directly or nest inside $cond for branching logic.

Bonus — Compare Two Document Fields

Check whether two fields match, ignoring case:

mongosh
db.users.aggregate([
  {
    $project: {
      email: 1,
      emailConfirm: 1,
      emailsMatch: {
        $eq: [
          { $strcasecmp: [ "$email", "$emailConfirm" ] },
          0
        ]
      }
    }
  }
])

How It Works

Both arguments can be field paths. Useful for validating that a confirmation field matches the original, even if the user typed different casing.

🚀 Use Cases

  • Status and role filtering — match "active", "admin", or other enums regardless of stored casing.
  • User input validation — compare form submissions to stored values without forcing lowercase on every write.
  • Duplicate detection — find records where two string fields should match case-insensitively.
  • Reporting flags — add computed booleans like isActive or isPremium in pipelines.

🧠 How $strcasecmp Works

1

MongoDB reads both strings

Each argument resolves to a string — from field paths, literals, or nested expressions.

Input
2

Case is normalized for comparison

MongoDB compares the strings as if uppercase and lowercase letters were equivalent.

Compare
3

A numeric result is returned

0 for equal, -1 if the first is less, 1 if the first is greater.

Output
=

Case-insensitive logic

Wrap in $eq ... 0 for equality, or use the number for ordering.

Conclusion

The $strcasecmp operator compares strings without regard to letter case and returns 0, -1, or 1. It is essential for case-insensitive filtering, validation, and conditional logic in aggregation pipelines and $expr queries.

For equality checks, always pair it with { $eq: [ { $strcasecmp: [...] }, 0 ] }. Next in the series: $strLenBytes.

💡 Best Practices

✅ Do

  • Use $strcasecmp when user input casing may differ from stored data
  • Check equality with { $eq: [ { $strcasecmp: [...] }, 0 ] }
  • Use inside $expr for find and $match filters
  • Compare two fields when validating confirmation inputs
  • Store canonical lowercase values if you need indexed exact-match queries without $expr

❌ Don’t

  • Expect a boolean — $strcasecmp returns a number, not true/false
  • Confuse it with $eq, which is case-sensitive for strings
  • Assume it trims whitespace — leading or trailing spaces still matter
  • Rely on it for locale-specific sorting (accents, Unicode rules)
  • Forget that null inputs propagate as null

Key Takeaways

Knowledge Unlocked

Five things to remember about $strcasecmp

Use these points when comparing strings in MongoDB.

5
Core concepts
🔢 02

0 / -1 / 1

Numeric result.

Returns
📝 03

[ s1, s2 ]

Two strings.

Syntax
🛠 04

$eq ... 0

Equality test.

Pattern
05

vs $eq

Case-sensitive.

Compare

❓ Frequently Asked Questions

$strcasecmp compares two strings without regard to letter case. It returns 0 when the strings match, -1 when the first string is less than the second, and 1 when the first is greater. Use it for case-insensitive equality checks and sorting logic.
The syntax is { $strcasecmp: [ <string1>, <string2> ] }. Both arguments can be field references like "$status" or literal strings like "active".
Compare the result to zero: { $eq: [ { $strcasecmp: [ "$field", "target" ] }, 0 ] }. This returns true when the strings match case-insensitively.
Normal comparison with $eq is case-sensitive: "Active" and "active" are not equal. $strcasecmp ignores case, so those two strings compare as equal (returns 0).
Yes. Wrap it inside $expr in a find filter or use it in aggregation $match stages. Example: { $expr: { $eq: [ { $strcasecmp: [ "$role", "admin" ] }, 0 ] } }.

Continue the Operator Series

Move on to $strLenBytes for byte-length string measurement, or review $concat for joining strings.

Next: $strLenBytes →

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