MongoDB $regexFindAll Operator

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

What You’ll Learn

The $regexFindAll operator finds every regular expression match in a string and returns them as an array. Use it when you need all hashtags, mentions, numbers, or tokens — not just the first one.

01

All Matches

Every regex hit.

02

Array Output

Match objects list.

03

idx + captures

Position and groups.

04

Aggregation

$project / $addFields.

05

Use Cases

Tokenize, count.

06

vs $regexFind

All vs first only.

Definition and Usage

In MongoDB’s aggregation framework, the $regexFindAll operator searches a string for a regular expression pattern and returns an array of match objects. Each object contains match (matched text), idx (start index), and captures (parenthesized groups).

When no matches are found, the result is an empty array [] — not null. This makes it easy to chain with $size, $map, or $filter without extra null checks.

💡
Beginner Tip

Need only the first match? Use $regexFind instead. Need only yes/no? Use $regexMatch. Use $regexFindAll when you want every occurrence with its text and position.

📝 Syntax

The $regexFindAll operator takes the same shape as $regexFind:

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

Return Shape

mongosh
// On one or more matches:
[
  { match: "first hit",  idx: 0,  captures: [] },
  { match: "second hit", idx: 12, captures: [] }
]

// No matches:
[]

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 all non-overlapping matches in left-to-right order.
  • Returns [] when there are no matches or when input is null.
  • Use inside $project, $addFields, or $set (MongoDB 4.2+).

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

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

⚡ Quick Reference

QuestionAnswer
Operator typeAggregation expression operator (string / regex)
Syntax{ $regexFindAll: { input, regex, options? } }
OutputArray of { match, idx, captures } objects
No match[] (empty array)
Common stages$project, $addFields, $set
Basic
{
  $regexFindAll: {
    input: "$text",
    regex: "#\\w+"
  }
}

All hashtags

Count matches
{ $size: "$tags" }

Array length

Map .match
$map + $$this.match

Strings only

No match
[]

Empty array

Examples Gallery

Collect every hashtag, count matches, extract mention handles, and map results to plain strings with $regexFindAll.

📚 Social Post Parsing

Extract every hashtag from a body field with $regexFindAll.

Sample Input Documents

Suppose you have a posts collection:

mongosh
[
  {
    "_id": 1,
    "author": "Alice",
    "body": "Love #mongodb and #database design!"
  },
  {
    "_id": 2,
    "author": "Bob",
    "body": "No hashtags in this post."
  },
  {
    "_id": 3,
    "author": "Carol",
    "body": "Thanks @alice and @bob for the help #teamwork"
  }
]

Example 1 — Extract All Hashtags

Find every hashtag in each post body:

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

How It Works

The pattern #\w+ matches each hash symbol plus word characters. Unlike $regexFind, all matches are returned. Posts with no hashtags get an empty array.

📈 Practical Patterns

Count matches, flatten to strings, and extract @mentions.

Example 2 — Count How Many Matches

Use $size on the result array:

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

// Alice: 2, Bob: 0, Carol: 1

How It Works

$size counts array elements. Because $regexFindAll always returns an array (even when empty), you do not need a null check before counting.

Example 3 — Map Results to Plain Strings

Store only the matched text, not the full match objects:

mongosh
db.posts.aggregate([
  {
    $project: {
      author: 1,
      tagList: {
        $map: {
          input: {
            $regexFindAll: {
              input: "$body",
              regex: "#\\w+"
            }
          },
          as: "hit",
          in: "$$hit.match"
        }
      }
    }
  }
])

// Alice: ["#mongodb", "#database"]
// Bob: []
// Carol: ["#teamwork"]

How It Works

$map walks each match object and projects $$hit.match. This is a common pattern when downstream stages expect a simple string array.

Example 4 — Extract All @Mentions

Pull every user mention from a post:

mongosh
db.posts.aggregate([
  {
    $project: {
      author: 1,
      mentions: {
        $map: {
          input: {
            $regexFindAll: {
              input: "$body",
              regex: "@(\\w+)"
            }
          },
          as: "m",
          in: {
            $arrayElemAt: [ "$$m.captures", 0 ]
          }
        }
      }
    }
  }
])

// Carol: ["alice", "bob"]

How It Works

The capture group (\w+) stores the username without the @ symbol. $map reads captures[0] from each match object.

Bonus — Extract All Numbers from Log Text

Parse numeric tokens from a log message field:

mongosh
db.logs.aggregate([
  {
    $project: {
      message: 1,
      numbers: {
        $map: {
          input: {
            $regexFindAll: {
              input: "$message",
              regex: "\\d+"
            }
          },
          as: "n",
          in: { $toInt: "$$n.match" }
        }
      }
    }
  }
])

// "Error 404 on port 8080" → numbers: [404, 8080]

How It Works

\d+ matches one or more digits. $toInt converts each matched string to a number for further math or filtering.

🚀 Use Cases

  • Token extraction — collect all hashtags, mentions, or keywords from free text.
  • Match counting — measure how often a pattern appears with $size.
  • Log parsing — pull every error code, IP address, or timestamp from messages.
  • Data normalization — build string arrays for tags, categories, or identifiers in ETL pipelines.

🧠 How $regexFindAll 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 scans the full string

MongoDB searches left to right and records every non-overlapping substring that satisfies the pattern.

Search
3

Each match becomes an array element

Every hit is stored as { match, idx, captures }. No matches produce [].

Collect
=

Array of all matches

Use $map, $size, or $filter on the result array.

Conclusion

The $regexFindAll operator finds every regular expression match in a string and returns them as an array of { match, idx, captures } objects. When nothing matches, you get [].

Pair it with $map to flatten results or $size to count them. For a single match, use $regexFind. For a boolean check, use $regexMatch. Next in the series: $regexMatch.

💡 Best Practices

✅ Do

  • Expect an array — use $size or $map on the result
  • Use $regexFind when you only need the first match
  • Use capture groups when extracting a specific part of each match
  • Handle empty arrays naturally (no null check needed)
  • Use $regexMatch for simple existence checks

❌ Don’t

  • Expect null for no match — the result is []
  • Use $regexFindAll as a query filter (it is expression-only)
  • Run greedy patterns on very large strings without testing performance
  • Assume overlapping matches are returned (MongoDB uses non-overlapping search)
  • Confuse $regexFindAll with query $regex

Key Takeaways

Knowledge Unlocked

Five things to remember about $regexFindAll

Use these points when extracting every regex match in pipelines.

5
Core concepts
📝 02

input + regex

Same as $regexFind.

Syntax
🛠 03

Array output

List of objects.

Output
🗃 04

$map / $size

Flatten or count.

Chaining
05

[]

No matches found.

Edge case

❓ Frequently Asked Questions

$regexFindAll searches a string for every regular expression match and returns an array of objects. Each object has match (matched text), idx (start position), and captures (capture groups). If nothing matches, it returns an empty array.
The syntax is { $regexFindAll: { input: <string>, regex: <pattern>, options: <options> } }. Use inside $project, $addFields, or $set. The options field is optional.
An array like [{ match: "...", idx: number, captures: [...] }, ...]. When there are no matches, the result is [] (an empty array), not null.
$regexFind returns only the first match as a single object or null. $regexFindAll returns every match in the string as an array of match objects.
Use $regexFindAll when you need the matched text, positions, or capture groups for every occurrence. Use $regexMatch when you only need a true/false answer about whether a pattern exists.

Continue the Operator Series

Move on to $regexMatch for boolean pattern checks, or review $regexFind for the first match only.

Next: $regexMatch →

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