$regexFind is a MongoDB aggregation expression that finds the first regex match inside a string and returns an object with the matched text, start index, and capture groups—or null if nothing matches.
Remember
$regexFind = extract first match (+ metadata)
{ $regexFind: {
input: <string>,
regex: <pattern>,
options: "<flags>" // optional
}
}
success → { match, idx, captures }
no match → null
$regex → filter documents
$regexFind → extract from a string
$regexFindAll → every match (array)
Optionally add options (such as "i") and read .match or .captures.
Piece
Required?
Role
input
Yes
String to search
regex
Yes
Pattern to find
options
No
Flags like i, m, s, x
Pseudocode
Pseudocode
text = evaluate(input)
if text is null or missing:
result = null
else:
m = first_regex_match(text, pattern, options)
if no match:
result = null
else:
result = {
match: matched_text,
idx: start_index,
captures: [ group1, group2, ... ]
}
emit { ..., field: result }
Reference
Cheat Sheet
Keep these facts handy while extracting matches in pipelines.
Topic
Detail
Type
Aggregation expression (not a find filter)
Syntax
{ $regexFind: { input, regex, options? } }
Success shape
{ match, idx, captures }
No match
null
idx
Zero-based start position
vs $regex
Extract vs filter documents
Sample
"Order #A42" → match "#A42"
Try it
Live Preview
Watch $regexFind pull the first match from a sample note string.
A shipping note says Order #A42 shipped today. We want the first order code that looks like # plus letters/digits.
Calculation
note = "Order #A42 shipped today"
↑
index 6
pattern = /#[A-Z0-9]+/
first match:
match = "#A42"
idx = 6
captures = [] // no ( ) groups
with /#([A-Z0-9]+)/:
match = "#A42"
captures = ["A42"] // group 1
Code
MongoDB Examples
We use one shipping note. First insert it, then extract the order code with $regexFind, then pull a capture group. Run these in mongosh after inserting the sample data once.
Example 1 — Sample Data
Imagine one note: Order #A42 shipped today. We save it in a collection named notes.
Add parentheses.#([A-Z0-9]+) still matches #A42, but group 1 is A42.
Fill captures.found.captures becomes ["A42"].
Pick the group.$arrayElemAt: ["$found.captures", 0] writes code: "A42".
Edge Cases & Pitfalls
Check these before extracting matches in production pipelines.
null
No match → null
If the pattern misses, the whole result is null—not an empty object. Guard before reading .match.
first
Only the first match
A second code later in the string is ignored. Use $regexFindAll for every match.
filter
Not a document filter
To keep/drop documents by pattern, use $regex in find / $match.
groups
Captures need ( )
Without parentheses, captures is []. Add groups when you need a piece of the match.
Analysis
Performance Notes
Approach
Cost
Best for
$regexFind per doc
Regex on one string
Pulling codes / tokens
Filter then extract
Fewer docs
Large collections
Store parsed field
No recompute
Hot query paths
Regex work is heavier than plain field reads. Filter early with $match when only some documents need extraction.
Remember
Key Takeaways
Role: extract the first regex match from a string.
Result:{ match, idx, captures } or null.
vs $regex: extract in aggregation vs filter in queries.
Sample:"#A42" at idx 6; capture "A42".
One line:$regexFind answers “what is the first regex match in this string, and where is it?”
Frequently Asked Questions
$regexFind searches a string for the first regular expression match and returns an object with match (matched text), idx (start index), and captures (capture groups). If nothing matches, it returns null.
Use { $regexFind: { input: <string>, regex: <pattern>, options: <options> } }. Place it inside stages such as $addFields or $project. The options field is optional.
On a match: { match: "...", idx: <number>, captures: [...] }. On no match: null. idx is the zero-based start position of the match.
$regex is a query filter that keeps or drops whole documents. $regexFind is an aggregation expression that extracts the first match (and metadata) from a string field.
$regexFind returns only the first match as one object (or null). $regexFindAll returns an array of all matches.
Parentheses in the pattern fill the captures array. For example, /#([A-Z0-9]+)/ on "Order #A42" yields match "#A42" and captures ["A42"].