MongoDB $substr Operator

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

What You’ll Learn

The $substr operator extracts part of a string starting at a zero-based index for a given length. Use it to pull prefixes, suffixes, IDs, and fixed-width segments from text fields in aggregation pipelines.

01

Substring

Slice any string.

02

Syntax

[ str, start, len ].

03

Zero-Based

Start at index 0.

04

$project Stage

New sliced fields.

05

Use Cases

Codes, masking, trim.

06

vs $substrCP

Legacy vs Unicode.

Definition and Usage

In MongoDB’s aggregation framework, the $substr operator returns a substring of a string. You specify where to start (zero-based index) and how many characters to include. For example, { $substr: [ "hello world", 0, 5 ] } returns "hello".

This is similar to JavaScript’s String.substring() or String.slice(). MongoDB also offers $substrBytes (byte positions) and $substrCP (code-point positions) for more precise Unicode handling.

💡
Beginner Tip

Index 0 is the first character. To skip the first three characters, use start 3. For international text and emoji, prefer $substrCP over $substr.

📝 Syntax

The $substr operator takes a string, start index, and length:

mongosh
{ $substr: [ <string>, <start>, <length> ] }

Literal Examples

mongosh
{ $substr: [ "hello world", 0, 5 ] }
// Result: "hello"

{ $substr: [ "hello world", 6, 5 ] }
// Result: "world"

{ $substr: [ "MongoDB", 0, 5 ] }
// Result: "Mongo"

Syntax Rules

  • First argument — string expression (field path or literal).
  • Second argument — zero-based start index (integer).
  • Third argument — number of characters to extract.
  • Use inside $project, $addFields, or $set.
  • Start beyond string length — returns "" (empty string).
  • null string — returns null.

💡 $substr vs $substrBytes vs $substrCP

$substr — legacy alias; behaves like byte-based slicing in current MongoDB
$substrBytes — start and length measured in UTF-8 bytes
$substrCP — start and length measured in Unicode code points (recommended for emoji/i18n)
For ASCII-only data, all three often produce the same result.

⚡ Quick Reference

QuestionAnswer
Operator typeAggregation expression operator (string)
Syntax{ $substr: [ string, start, length ] }
Start indexZero-based (0 = first character)
OutputSubstring string or null
Modern alternative$substrCP or $substrBytes
Common stages$project, $addFields, $set
First 5
{
  $substr: ["$text", 0, 5]
}

Prefix slice

Skip prefix
{
  $substr: ["$code", 3, 4]
}

From index 3

Literal
{
  $substr: ["hello", 1, 3]
}

Returns "ell"

Empty start
start >= length
→ ""

Out of range

Examples Gallery

Extract prefixes, pull fixed-width codes, skip headers, and mask sensitive values with $substr.

📚 Basic Substring Extraction

Start with a products collection and slice string fields with $project.

Sample Input Documents

Suppose you have a products collection with SKU and description fields:

mongosh
[
  { "_id": 1, "sku": "ELEC-00123", "description": "Wireless Mouse" },
  { "_id": 2, "sku": "BOOK-00456", "description": "MongoDB Guide" },
  { "_id": 3, "sku": "FOOD-00789", "description": "Organic Tea" }
]

Example 1 — Basic $substr on a Field

Extract the first five characters of the description:

mongosh
db.products.aggregate([
  {
    $project: {
      description: 1,
      shortDesc: {
        $substr: [ "$description", 0, 5 ]
      }
    }
  }
])

How It Works

Start at index 0 and take 5 characters. The result is a new string field in the output document.

📈 Prefixes, Codes, and Masking

Parse structured strings and hide sensitive parts of values.

Example 2 — Extract Category Prefix from SKU

Pull the four-letter category code before the hyphen:

mongosh
db.products.aggregate([
  {
    $project: {
      sku: 1,
      category: {
        $substr: [ "$sku", 0, 4 ]
      }
    }
  }
])

// "ELEC-00123" → category: "ELEC"
// "BOOK-00456" → category: "BOOK"

How It Works

When values follow a fixed pattern, $substr quickly extracts the leading segment without needing $split.

Example 3 — Skip a Fixed Prefix

Remove the first five characters (e.g., a country code prefix):

mongosh
db.orders.aggregate([
  {
    $project: {
      orderRef: 1,
      localRef: {
        $substr: [ "$orderRef", 5, 10 ]
      }
    }
  }
])

// orderRef: "US-ORD-12345"
// Skip "US-OR" (5 chars), take next 10 → "D-12345" (depends on length param)

How It Works

Increase the start index to skip a known prefix. Adjust length to capture the segment you need, or use a large length to grab the rest (MongoDB stops at the string end).

Example 4 — Mask a Phone Number

Show only the last four digits by combining $strLenCP and $substr:

mongosh
db.users.aggregate([
  {
    $project: {
      phone: 1,
      masked: {
        $concat: [
          "****",
          {
            $substr: [
              "$phone",
              { $subtract: [ { $strLenCP: "$phone" }, 4 ] },
              4
            ]
          }
        ]
      }
    }
  }
])

// "5551234567" → masked: "****4567"

How It Works

Calculate start as total length minus 4, then extract the last four characters and prepend asterisks with $concat.

Bonus — Extract “world” from “hello world”

Classic substring demo with a literal string:

mongosh
db.samples.aggregate([
  {
    $project: {
      greeting: { $substr: [ "hello world", 0, 5 ] },
      target:   { $substr: [ "hello world", 6, 5 ] }
    }
  }
])

// greeting: "hello"
// target:   "world"

How It Works

The space at index 5 is skipped when you start the second slice at index 6. This mirrors how zero-based indexing works in most programming languages.

🚀 Use Cases

  • Fixed-width parsing — extract category codes, region prefixes, or legacy ID segments.
  • Display truncation — show a short preview of long text fields in reports.
  • Data masking — hide all but the last few digits of phone numbers or account IDs.
  • Normalization — strip known prefixes before matching or grouping.

🧠 How $substr Works

1

MongoDB reads the string

The first argument resolves to a string from a field path or literal.

Input
2

Start index is applied

MongoDB moves to the zero-based start position. If start is past the end, the result is empty.

Position
3

Length characters are taken

The operator returns up to length characters from that position.

Extract
=

Substring returned

Use in $project, combine with $concat, or chain with other string ops.

Conclusion

The $substr operator extracts part of a string using a zero-based start index and a length. It is a foundational tool for parsing fixed-width text, truncating display values, and masking sensitive data in aggregation pipelines.

For Unicode-heavy content, prefer $substrCP or $substrBytes. Next in the series: $substrBytes.

💡 Best Practices

✅ Do

  • Use $substr for ASCII fixed-width parsing and simple slices
  • Prefer $substrCP when emoji or international text is involved
  • Combine with $strLenCP to slice from the end (masking)
  • Guard null fields with $ifNull before slicing
  • Test edge cases: empty strings, start beyond length, length longer than remainder

❌ Don’t

  • Assume one index unit equals one visible character for all Unicode text
  • Confuse $substr with $slice (arrays vs strings)
  • Use negative start indices — $substr requires non-negative start
  • Forget that out-of-range start returns an empty string, not an error
  • Hard-code byte positions for UTF-8 text — use $substrCP instead

Key Takeaways

Knowledge Unlocked

Five things to remember about $substr

Use these points when slicing strings in MongoDB.

5
Core concepts
📝 02

[ s, start, len ]

Three arguments.

Syntax
🔢 03

Index 0

Zero-based start.

Rule
🛠 04

Masking

Last N digits.

Pattern
05

vs $substrCP

Unicode-safe.

Compare

❓ Frequently Asked Questions

$substr returns part of a string starting at a zero-based index for a given length. For example, { $substr: [ "hello world", 0, 5 ] } returns "hello". It is used inside aggregation stages like $project and $addFields.
The syntax is { $substr: [ <string>, <start>, <length> ] }. Start is the zero-based index where extraction begins; length is how many characters to include.
$substr is a legacy alias. MongoDB recommends $substrBytes (byte-based positions) or $substrCP (code-point positions) for Unicode-safe substring extraction. $substr behaves like $substrBytes in current versions.
$substr returns an empty string when the start index is greater than or equal to the string length.
If the string expression is null, $substr returns null. Use $ifNull to provide a default empty string when the field may be missing.

Continue the Operator Series

Move on to $substrBytes for byte-based substring extraction, or review $strLenCP for character counting.

Next: $substrBytes →

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