Regex Sorguları ve Örüntü Eşleştirme
Öğrenenler, esnek metin örüntüsü aramaları için dize alanlarına düzenli ifadeler uygulayacaktır.
Regex Sorguları ve Örüntü Eşleştirme, CoddyKit'te ücretsiz bir MongoDB Academy dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, MongoDB Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. MongoDB Academy kursu toplamda 4 dersten oluşur.
Bu dersin bazı bölümleri henüz çevrilmemiş olup İngilizce olarak gösterilmektedir.
When You Need Pattern Matching
Sometimes you need to search for documents where a string field contains, starts with, or ends with a certain pattern—but you do not know the exact value. Simple equality filters like { name: 'Alice' } only match exact strings. Regular expressions (regex) give you flexible pattern matching against string fields in MongoDB.
MongoDB supports regex through the $regex operator or by passing a JavaScript regex literal directly in a query filter. Both approaches work, with slightly different syntax for setting options like case-insensitivity.
Basic Regex Syntax in MongoDB
There are two ways to use regex in MongoDB queries:
- JS regex literal:
{ name: /alice/i }— concise, flags go after the closing slash - $regex operator:
{ name: { $regex: 'alice', $options: 'i' } }— more verbose but required when combining with other operators
Both forms produce identical results. Use the JS literal syntax for simple queries; use the $regex operator form when you need to build the pattern dynamically from a string variable or combine it with other operators on the same field.
// JS regex literal - concise
db.users.find({ name: /alice/i });
// 'i' flag = case-insensitive
// $regex operator - equivalent
db.users.find({ name: { $regex: 'alice', $options: 'i' } });
// Dynamic pattern from variable:
const searchTerm = req.query.name;
const escapedTerm = searchTerm.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // Escape special chars
db.users.find({ name: { $regex: escapedTerm, $options: 'i' } });Regex Options: i, m, s, x
MongoDB supports four regex option flags:
i— Case-insensitive:/alice/imatches 'Alice', 'ALICE', 'alice'm— Multiline:^and$match the start/end of each line rather than the whole strings— Dot-all:.matches any character including newlinesx— Extended: whitespace in the pattern is ignored (for readable patterns with comments)
The most commonly used flag is i. The m flag is useful for searching multi-line text fields like blog content. Multiple flags can be combined: { $options: 'im' }.
// Case-insensitive search for 'javascript'
db.courses.find({ title: { $regex: 'javascript', $options: 'i' } });
// Matches: 'JavaScript', 'JAVASCRIPT', 'javascript', 'JavaScript Tutorial'
// Multiline match: ^ anchors to start of each line
db.articles.find({ content: { $regex: '^Introduction', $options: 'm' } });
// Matches articles where any line starts with 'Introduction'
// Combined flags
db.posts.find({ body: { $regex: 'mongodb', $options: 'si' } });
// Case-insensitive + dot matches newlines in bodyAnchors: Starts With and Ends With
Use regex anchors to match the start or end of a string field:
^anchors to the start:/^Admin/matches strings that begin with 'Admin'$anchors to the end:/\.pdf$/matches strings ending with '.pdf'
A critical performance fact: a prefix regex with a caret (/^prefix/) CAN use a regular B-tree index on that field—MongoDB can seek directly to the prefix in the index. This makes prefix searches much faster than mid-string searches. Never use a leading wildcard (/.*pattern/ or /pattern/ without ^) on a large collection without a text index.
// Prefix match - CAN use index (very efficient)
db.users.find({ username: /^admin/i });
// Matches: 'admin', 'administrator', 'Admin123'
// Uses the index on username (if it exists)
// Suffix match - CANNOT use regular index (slower)
db.files.find({ filename: /\.pdf$/i });
// Matches: 'report.pdf', 'invoice.PDF'
// Must scan all documents - add text index if used frequently
// Mid-string - CANNOT use index
db.products.find({ description: /wireless/i });
// Must scan all documents - use $text index for thisCharacter Classes and Quantifiers
Regex gives you expressive pattern primitives:
.— any character (except newline, unlesssflag set)[abc]— character class: matches a, b, or c[a-z]— range: any lowercase letter\d— any digit (equivalent to[0-9])\w— any word character ([a-zA-Z0-9_])*,+,?— zero or more, one or more, zero or one{n},{n,m}— exactly n, between n and m occurrences
// Phone number pattern: +1-XXX-XXX-XXXX or similar
db.users.find({ phone: /^\+?\d{1,3}[-. ]?\(?\d{3}\)?[-. ]?\d{3}[-. ]?\d{4}$/ });
// 6-character alphanumeric codes
db.coupons.find({ code: /^[A-Z0-9]{6}$/ });
// Matches: 'SALE99', 'DISC25', 'FREE01'
// Email basic validation
db.users.find({ email: { $regex: '^[\\w.]+@[\\w.]+\\.[a-z]{2,}$', $options: 'i' } });Regex vs Text Index: Know the Difference
Regex queries and MongoDB's $text operator serve different purposes and have very different performance characteristics:
- Regex: matches by character pattern. Works on any string field, no special index needed (though prefix anchors use B-tree indexes). Suitable for format validation, prefix search, or pattern matching on small collections or indexed prefix queries.
- $text / text index: full-text keyword search with tokenization, stemming, and stop-word filtering. Requires a text index. Much faster for keyword search in large text fields (articles, descriptions, comments).
Never use /.*keyword.*/i on a large unindexed collection—it is a full scan and may be slow.
// Use REGEX for: format matching, prefix searches on indexed field
db.orders.find({ orderNumber: /^ORD-2024/ }); // Prefix - can use index
// Use $text for: keyword search in content fields
// First: create a text index
db.articles.createIndex({ content: 'text', title: 'text' });
// Then: full-text search
db.articles.find({ $text: { $search: 'mongodb performance' } });
// Much faster than /mongodb.*performance/i on large collectionsReDoS: The Security Risk
ReDoS (Regular Expression Denial of Service) is an attack where a malicious user crafts an input string that causes a poorly written regex to take exponential time to evaluate. If you pass user input directly into a regex without escaping, an attacker can hang your database query.
Always escape user input before using it in a regex by replacing all special regex characters (. * + ? ^ $ { } ( ) [ ] | \ ) with their escaped equivalents. Many libraries (like escape-string-regexp in Node.js) do this automatically. Additionally, prefer $text for user-facing search inputs over raw regex.
// DANGEROUS: raw user input in regex (ReDoS risk)
const input = req.query.search; // User controls this
db.products.find({ name: { $regex: input } }); // NEVER DO THIS
// SAFE: escape user input before using in regex
function escapeRegex(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
const safeInput = escapeRegex(req.query.search);
db.products.find({ name: { $regex: safeInput, $options: 'i' } });
// BETTER: Use $text for user-facing search
db.products.find({ $text: { $search: req.query.search } });Regex on Array Fields
When you apply a regex to an array field, MongoDB checks whether any element of the array matches the pattern—the same containment semantics as equality queries on arrays. This lets you search through arrays of tags, categories, or any string array without a special operator.
For example, a document with tags: ['node.js', 'mongodb', 'backend'] would be returned by { tags: /^mongo/ } because 'mongodb' starts with 'mongo'. The regex is applied to each element independently.
// Document: { tags: ['node.js', 'mongodb', 'backend-dev'] }
// Find products where any tag starts with 'mongo'
db.products.find({ tags: /^mongo/i });
// Returns the document (tags contains 'mongodb')
// Find articles where any category contains 'tech'
db.articles.find({ categories: /tech/i });
// Matches: categories containing 'technology', 'tech-news', 'fintech'
// Index on array field improves regex prefix searches
db.articles.createIndex({ categories: 1 });Practical Search Example
A typical e-commerce search feature combines regex with other filters to provide a contextual, case-insensitive product search. The query matches product names that contain the search term anywhere in the string, filtered by category and in-stock status.
For small catalogs (under 50,000 products), regex search is acceptable. For larger catalogs or full-description search, Atlas Search (Lucene-based) provides superior relevance ranking, stemming, and performance.
// Search endpoint: GET /products?q=wireless&category=Electronics
app.get('/products', async (req, res) => {
const filter = { stock: { $gt: 0 } };
if (req.query.q) {
const escaped = req.query.q.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
filter.name = { $regex: escaped, $options: 'i' };
}
if (req.query.category) {
filter.category = req.query.category;
}
const products = await db.collection('products')
.find(filter)
.project({ name: 1, price: 1, _id: 1 })
.limit(50)
.toArray();
res.json(products);
});Regex Performance Summary
Key rules for regex performance in MongoDB:
- Prefix with
^(/^prefix/): Can use a B-tree index. Best performance for regex. - Case-sensitive prefix (
/^prefix/): Fully exploits index ordering. - Case-insensitive prefix (
/^prefix/i): Partially uses index but still much faster than no anchor. - Contains without anchor (
/pattern/): Full collection scan—use text index instead. - Suffix (
/pattern$/): Full collection scan or text index.
When in doubt, test with explain('executionStats') and look for IXSCAN vs COLLSCAN.
// Check if regex query uses an index
db.users.find({ username: /^alice/i })
.explain('executionStats');
// winningPlan.stage should be 'IXSCAN' if username is indexed
// Compare index scan vs collection scan:
// /^alice/ on indexed field: totalDocsExamined ~= nReturned (efficient)
// /alice/ on any field: totalDocsExamined = all documents (slow!)Testing Regex Patterns Before Deployment
Before running a regex query on a production collection, test the pattern against sample documents to verify it matches what you intend and does not match what you do not intend. The MongoDB shell lets you test quickly with a small limit(), and JavaScript's String.prototype.test() or regex literals let you validate patterns in Node.js before embedding them in queries.
Also check performance with explain(): a regex that requires a full collection scan should be converted to a text query or have its collection size considered. For new collections, design with search requirements in mind—add text indexes from the start rather than retrofitting them.
// Step 1: Test regex in Node.js before using in query
const pattern = /^wireless/i;
const testStrings = ['Wireless Headphones', 'wireless mouse', 'Wired Keyboard'];
testStrings.forEach(s => console.log(s, '=>', pattern.test(s)));
// 'Wireless Headphones' => true
// 'wireless mouse' => true
// 'Wired Keyboard' => false
// Step 2: Test on production with limit
db.products.find({ name: /^wireless/i }).limit(5);
// Step 3: Check performance
db.products.find({ name: /^wireless/i }).explain('executionStats');Quick Check
Test your understanding of MongoDB & NoSQL Databases concepts from this lesson.
Lesson Recap
In this lesson you learned: regex queries use /pattern/flags or $regex operator for flexible string pattern matching—the most important flag is i for case-insensitivity, prefix-anchored regexes (/^prefix/) can use B-tree indexes for efficient lookups while mid-string patterns require full scans, and always escape user input before inserting it into a regex to prevent ReDoS attacks—or better yet, use the $text operator with a text index for user-facing search. Next up we move into updating documents with $set, $unset, and other update operators.
Sıkça Sorulan Sorular
“Regex Sorguları ve Örüntü Eşleştirme” dersi ücretsiz mi?
Evet — “Regex Sorguları ve Örüntü Eşleştirme” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve MongoDB Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. MongoDB Academy kursu toplamda 4 dersten oluşur.
“Regex Sorguları ve Örüntü Eşleştirme” dersinde ne öğreneceğim?
Öğrenenler, esnek metin örüntüsü aramaları için dize alanlarına düzenli ifadeler uygulayacaktır. MongoDB Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
MongoDB Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te MongoDB Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.
“Regex Sorguları ve Örüntü Eşleştirme” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu MongoDB Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her MongoDB Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Karşılaştırma Operatörleri: $eq, $gt, $lt, $in
- Mantıksal Operatörler: $and, $or, $nor, $not
- Öğe Operatörleri ve Tür Denetimleri
- Regex Sorguları ve Örüntü Eşleştirme