MongoDB $regexFind Operator

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

What You’ll Learn

The $regexFind operator finds the first regular expression match in a string and returns match details. Use it in aggregation pipelines to extract emails, hashtags, codes, or any substring without filtering entire documents.

01

Extract Match

First regex hit.

02

match + idx

Text and position.

03

Captures

Capture groups.

04

Aggregation

$project / $addFields.

05

Use Cases

Parse, validate.

06

vs $regex

Extract vs filter.

Definition and Usage

In MongoDB’s aggregation framework, the $regexFind operator searches a string for a regular expression pattern and returns metadata about the first match. The result is an object with match (matched text), idx (start index), and captures (parenthesized groups). If nothing matches, the result is null.

Unlike query $regex, which filters documents, $regexFind transforms data inside pipelines. It is ideal for parsing log messages, extracting domains from emails, or pulling SKU prefixes into separate fields.

💡
Beginner Tip

Access the matched text with $matchResult.match after projecting the full $regexFind result, or use dot notation in a nested $project. Need all matches? Use $regexFindAll instead.

📝 Syntax

The $regexFind operator takes an object with input, regex, and optional options:

mongosh
{
  $regexFind: {
    input: <string expression>,
    regex: <pattern expression>,
    options: <options expression>  // optional
  }
}

Return Shape

mongosh
// On match:
{
  match: "matched substring",
  idx: 12,           // zero-based start index
  captures: []       // capture group strings
}

// No match:
null

Syntax Rules

  • input — the string to search (field path or expression).
  • regex — the pattern string or BSON regex literal.
  • options — optional flags like "i" (case insensitive).
  • Returns only the first match in the string.
  • Returns null when there is no match or when input is null.
  • Use inside $project, $addFields, or $set (MongoDB 4.2+).

💡 $regexFind vs $regex vs $regexFindAll vs $regexMatch

$regex — query filter; returns matching documents
$regexFind — aggregation expression; first match object or null
$regexFindAll — aggregation expression; array of all matches
$regexMatch — aggregation expression; true/false only (no extraction)

⚡ Quick Reference

QuestionAnswer
Operator typeAggregation expression operator (string / regex)
Syntax{ $regexFind: { input, regex, options? } }
Output{ match, idx, captures } or null
Matches returnedFirst match only
Common stages$project, $addFields, $set
Basic
{
  $regexFind: {
    input: "$text",
    regex: "#\\w+"
  }
}

Find hashtag

Case insensitive
{
  options: "i"
}

Ignore case

Get .match
"$result.match"

Matched text

No match
null

Pattern not found

Examples Gallery

Extract hashtags from posts, parse email domains, pull capture groups, and check whether a pattern exists with $cond.

📚 Social Post Parsing

Extract the first hashtag from a body field with $regexFind.

Sample Input Documents

Suppose you have a posts collection:

mongosh
[
  {
    "_id": 1,
    "author": "Alice",
    "body": "Learning MongoDB #database today!"
  },
  {
    "_id": 2,
    "author": "Bob",
    "body": "No hashtags here."
  },
  {
    "_id": 3,
    "author": "Carol",
    "email": "carol.smith@gmail.com"
  }
]

Example 1 — Extract First Hashtag

Find the first hashtag in each post body:

mongosh
db.posts.aggregate([
  {
    $project: {
      author: 1,
      body: 1,
      hashtag: {
        $regexFind: {
          input: "$body",
          regex: "#\\w+"
        }
      }
    }
  }
])

How It Works

The pattern #\w+ matches a hash symbol followed by word characters. Only the first hashtag is returned. Posts without a match get null.

📈 Practical Patterns

Parse domains, use capture groups, and project just the matched text.

Example 2 — Extract Email Domain

Pull the domain portion from an email address:

mongosh
db.posts.aggregate([
  {
    $match: { email: { $exists: true } }
  },
  {
    $project: {
      author: 1,
      email: 1,
      domain: {
        $let: {
          vars: {
            found: {
              $regexFind: {
                input: "$email",
                regex: "@(.+)$"
              }
            }
          },
          in: {
            $arrayElemAt: [ "$$found.captures", 0 ]
          }
        }
      }
    }
  }
])

// carol.smith@gmail.com → domain: "gmail.com"

How It Works

The capture group (.+) stores text after @ in captures[0]. $let stores the match result so you can read the capture group cleanly.

Example 3 — Project Only the Matched Text

Store just the matched substring, not the full result object:

mongosh
db.posts.aggregate([
  {
    $project: {
      author: 1,
      firstTag: {
        $getField: {
          field: "match",
          input: {
            $regexFind: {
              input: "$body",
              regex: "#\\w+"
            }
          }
        }
      }
    }
  }
])

// firstTag: "#database" or null

How It Works

$getField safely reads match from the result object. You can also use $ifNull when the field might be missing.

Example 4 — Check If Pattern Exists

Use $cond to set a boolean flag from the match result:

mongosh
db.posts.aggregate([
  {
    $project: {
      author: 1,
      hasHashtag: {
        $cond: [
          {
            $ne: [
              {
                $regexFind: {
                  input: "$body",
                  regex: "#\\w+"
                }
              },
              null
            ]
          },
          true,
          false
        ]
      }
    }
  }
])

How It Works

Compare the $regexFind result to null. For a simple true/false check without match text, consider $regexMatch instead.

Bonus — Extract SKU Prefix

Parse a product code prefix from a SKU string:

mongosh
db.products.aggregate([
  {
    $project: {
      sku: 1,
      category: {
        $regexFind: {
          input: "$sku",
          regex: "^(PRO|DEV|TEST)-",
          options: "i"
        }
      }
    }
  }
])

// sku: "PRO-1001" → match: "PRO-", idx: 0

How It Works

Alternation (PRO|DEV|TEST) matches any of those prefixes. The i option allows case-insensitive matching.

🚀 Use Cases

  • String parsing — extract hashtags, mentions, or codes from free text.
  • Email / URL parsing — pull domains, usernames, or TLDs with capture groups.
  • Log analysis — extract error codes or timestamps from message fields.
  • Data enrichment — add derived fields in ETL pipelines without application-side regex.

🧠 How $regexFind Works

1

MongoDB evaluates input and regex

The pipeline resolves the string (input) and compiles the pattern (regex) with any options.

Input
2

The engine finds the first match

MongoDB scans the string left to right and stops at the first substring that satisfies the pattern.

Search
3

Match metadata is returned

On success: match, idx, and captures. On failure: null.

Output
=

Extracted substring data

Use .match or captures in downstream pipeline stages.

Conclusion

The $regexFind operator extracts the first regular expression match from a string inside MongoDB aggregation pipelines. It returns match, idx, and captures — or null when nothing matches.

Use it for parsing and enrichment; use query $regex to filter documents. For all matches, switch to $regexFindAll. Next in the series: $regexFindAll.

💡 Best Practices

✅ Do

  • Handle null results with $ifNull or $cond
  • Use capture groups when you need a specific part of the match
  • Read .match or captures[0] in a follow-up projection
  • Use $regexMatch when you only need true/false
  • Escape special regex characters in literal patterns

❌ Don’t

  • Expect all matches — use $regexFindAll for that
  • Use $regexFind as a query filter (it is expression-only)
  • Assume captures is always non-empty (depends on groups)
  • Run complex regex on huge strings without considering performance
  • Confuse $regexFind with query $regex

Key Takeaways

Knowledge Unlocked

Five things to remember about $regexFind

Use these points when extracting regex matches in pipelines.

5
Core concepts
📝 02

input + regex

String and pattern.

Syntax
🛠 03

match / idx

Text + position.

Output
🗃 04

captures[]

Group extraction.

Groups
05

null

No match found.

Edge case

❓ Frequently Asked Questions

$regexFind searches a string for the first regular expression match and returns an object with match (the matched text), idx (start position), and captures (capture groups). If no match is found, it returns null.
The syntax is { $regexFind: { input: <string>, regex: <pattern>, options: <options> } }. Use inside $project, $addFields, or $set. The options field is optional.
On success: { match: "...", idx: number, captures: [...] }. On failure: null. The match field contains the first matched substring; idx is the zero-based start index.
$regex is a query filter that includes or excludes whole documents. $regexFind is an aggregation expression that extracts the matched portion of a string field and returns match metadata.
$regexFind returns only the first match as a single object (or null). $regexFindAll returns an array of all matches in the string.

Continue the Operator Series

Move on to $regexFindAll for every match in a string, or review $regex for document filtering.

Next: $regexFindAll →

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