Regex-queries en patroonherkenning
U past reguliere expressies toe op stringvelden voor flexibele zoekopdrachten op tekstpatronen.
Regex-queries en patroonherkenning is een gratis MongoDB Academy-les op CoddyKit. Dit is les 4 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject MongoDB Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus MongoDB Academy bevat in totaal 4 lessen.
Wanneer u patroonherkenning nodig hebt
Soms moet u zoeken naar documenten waarvan een stringveld een bepaald patroon bevat, ermee begint of ermee eindigt—maar u kent de exacte waarde niet. Eenvoudige gelijkheidsfilters zoals { name: 'Alice' } vinden alleen exact overeenkomende strings. Reguliere expressies (regex) bieden flexibele patroonherkenning voor stringvelden in MongoDB.
MongoDB ondersteunt regex via de operator $regex of door rechtstreeks een JavaScript-regexliteral door te geven in een queryfilter. Beide benaderingen werken, met enigszins verschillende syntaxis voor het instellen van opties zoals hoofdletterongevoeligheid.
Basisregexsyntaxis in MongoDB
Er zijn twee manieren om regex te gebruiken in MongoDB-query's:
- JS-regexliteral:
{ name: /alice/i }— beknopt, vlaggen staan na de afsluitende schuine streep - $regex-operator:
{ name: { $regex: 'alice', $options: 'i' } }— uitgebreider, maar vereist wanneer u deze met andere operators combineert
Beide vormen leveren identieke resultaten op. Gebruik de syntaxis met een JS-literal voor eenvoudige query's; gebruik de vorm met de $regex-operator wanneer u het patroon dynamisch uit een stringvariabele moet opbouwen of deze met andere operators op hetzelfde veld moet combineren.
// 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' } });Regexopties: i, m, s, x
MongoDB ondersteunt vier regex-optievlaggen:
i— Hoofdletterongevoelig:/alice/ivindt 'Alice', 'ALICE' en 'alice'm— Meerdere regels:^en$komen overeen met het begin en einde van elke regel in plaats van met de volledige strings— Punt voor alle tekens:.komt overeen met elk teken, inclusief regeleindenx— Uitgebreid: witruimte in het patroon wordt genegeerd (voor leesbare patronen met opmerkingen)
De meest gebruikte vlag is i. De vlag m is handig voor het zoeken in tekstvelden met meerdere regels, zoals bloginhoud. U kunt meerdere vlaggen combineren: { $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 bodyAnkers: beginnen met en eindigen op
Gebruik regex-ankers om het begin of einde van een stringveld te vinden:
^verankert aan het begin:/^Admin/vindt strings die met 'Admin' beginnen$verankert aan het einde:/\.pdf$/vindt strings die eindigen op '.pdf'
Een belangrijk prestatiekenmerk: een prefix-regex met een dakje (/^prefix/) KAN een gewone B-tree-index op dat veld gebruiken—MongoDB kan rechtstreeks naar het prefix in de index springen. Hierdoor zijn zoekopdrachten naar een prefix veel sneller dan zoekopdrachten midden in een string. Gebruik nooit een vooraanstaande jokertekenzoekopdracht (/.*pattern/ of /pattern/ zonder ^) op een grote verzameling zonder tekstindex.
// 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 thisTekensets en kwantoren
Regex biedt krachtige patroonbouwstenen:
.— elk teken (behalve een regeleinde, tenzij de vlagsis ingesteld)[abc]— tekenset: komt overeen met a, b of c[a-z]— bereik: elke kleine letter\d— elk cijfer (gelijk aan[0-9])\w— elk woordteken ([a-zA-Z0-9_])*,+,?— nul of meer, één of meer, nul of één{n},{n,m}— precies n, tussen n en m keer
// 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 versus tekstindex: ken het verschil
Regex-query's en MongoDB's $text-operator dienen verschillende doelen en hebben zeer verschillende prestatiekenmerken:
- Regex: zoekt op basis van een tekenpatroon. Werkt op elk stringveld en vereist geen speciale index (hoewel prefixankers B-tree-indexen gebruiken). Geschikt voor formaatvalidatie, zoeken op prefix of patroonherkenning in kleine collecties of geïndexeerde prefixquery's.
- $text / tekstindex: zoeken naar volledige tekst met tokenisatie, stemming en filtering van stopwoorden. Vereist een tekstindex. Veel sneller voor het zoeken naar trefwoorden in grote tekstvelden (artikelen, beschrijvingen en opmerkingen).
Gebruik nooit /.*keyword.*/i op een grote verzameling zonder index—dit doorzoekt de hele verzameling en kan traag zijn.
// 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: het beveiligingsrisico
ReDoS (Regular Expression Denial of Service) is een aanval waarbij een kwaadwillende gebruiker een invoerstring samenstelt die ervoor zorgt dat een slecht geschreven regex exponentieel veel tijd nodig heeft om te worden geëvalueerd. Als u gebruikersinvoer rechtstreeks in een regex plaatst zonder deze te escapen, kan een aanvaller uw databasequery laten vastlopen.
Escape gebruikersinvoer altijd voordat u deze in een regex gebruikt, door alle speciale regex-tekens (. * + ? ^ $ { } ( ) [ ] | \ ) te vervangen door hun geëscape-tegenhangers. Veel bibliotheken, zoals escape-string-regexp in Node.js, doen dit automatisch. Geef bovendien de voorkeur aan $text boven onbewerkte regex voor zoekinvoer die door gebruikers wordt opgegeven.
// 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 op arrayvelden
Wanneer u een regex toepast op een arrayveld, controleert MongoDB of een element van de array met het patroon overeenkomt—dezelfde insluitingssemantiek als bij gelijkheidsquery's op arrays. Hiermee kunt u zoeken in arrays met tags, categorieën of andere arrays met strings zonder een speciale operator.
Een document met tags: ['node.js', 'mongodb', 'backend'] zou bijvoorbeeld worden geretourneerd door { tags: /^mongo/ }, omdat 'mongodb' met 'mongo' begint. De regex wordt afzonderlijk op elk element toegepast.
// 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 });Praktisch zoekvoorbeeld
Een typische zoekfunctie voor e-commerce combineert regex met andere filters om contextueel en hoofdletterongevoelig naar producten te zoeken. De query vindt productnamen die de zoekterm ergens in de string bevatten, en filtert op categorie en voorraadstatus.
Voor kleine catalogi (minder dan 50.000 producten) is zoeken met regex acceptabel. Voor grotere catalogi of zoeken in volledige beschrijvingen biedt Atlas Search (op Lucene gebaseerd) een betere relevantierangschikking, stemming en prestaties.
// 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);
});Samenvatting van regexprestaties
Belangrijke regels voor regexprestaties in MongoDB:
- Prefix met
^(/^prefix/): kan een B-tree-index gebruiken. Beste prestaties voor regex. - Hoofdlettergevoelig prefix (
/^prefix/): benut de indexvolgorde volledig. - Hoofdletterongevoelig prefix (
/^prefix/i): gebruikt de index gedeeltelijk, maar is nog steeds veel sneller dan zonder anker. - Bevat zonder anker (
/pattern/): doorzoekt de hele verzameling—gebruik in plaats daarvan een tekstindex. - Achtervoegsel (
/pattern$/): doorzoekt de hele verzameling of gebruikt een tekstindex.
Als u twijfelt, test u met explain('executionStats') en kijkt u naar IXSCAN tegenover 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!)Regexpatronen testen vóór implementatie
Voordat u een regex-query uitvoert op een productieverzameling, test u het patroon met voorbeelddocumenten om te controleren of het overeenkomt met wat u bedoelt en niet met wat u niet bedoelt. In de MongoDB-shell kunt u dit snel testen met een kleine limit(), en met JavaScript's String.prototype.test() of regexliterals kunt u patronen in Node.js valideren voordat u ze in query's opneemt.
Controleer ook de prestaties met explain(): een regex waarvoor de hele verzameling moet worden doorzocht, moet worden omgezet in een tekstquery, of u moet rekening houden met de grootte van de verzameling. Ontwerp nieuwe collecties met de zoekvereisten in gedachten—voeg vanaf het begin tekstindexen toe in plaats van deze achteraf in te bouwen.
// 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');Korte controle
Test uw begrip van de concepten uit deze les over MongoDB en NoSQL-databases.
Samenvatting van de les
In deze les hebt u geleerd: regex-query's gebruiken /pattern/flags of de $regex-operator voor flexibele patroonherkenning in strings—de belangrijkste vlag is i voor hoofdletterongevoeligheid; regex-query's met een prefixanker (/^prefix/) kunnen B-tree-indexen gebruiken voor efficiënte zoekopdrachten, terwijl patronen midden in een string volledige scans vereisen; en u moet gebruikersinvoer altijd escapen voordat u deze in een regex invoegt om ReDoS-aanvallen te voorkomen—of, nog beter, de $text-operator met een tekstindex gebruiken voor zoekopdrachten door gebruikers. Hierna gaan we documenten bijwerken met $set, $unset en andere update-operators.
Leer JavaScript met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 30
- Lessen
- 120
Veelgestelde vragen
Is de les “Regex-queries en patroonherkenning” gratis?
Ja — de volledige tekst van “Regex-queries en patroonherkenning” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus MongoDB Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus MongoDB Academy bevat in totaal 4 lessen.
Wat leer ik in “Regex-queries en patroonherkenning”?
U past reguliere expressies toe op stringvelden voor flexibele zoekopdrachten op tekstpatronen. Je oefent met MongoDB Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met MongoDB Academy te beginnen?
Ervaring vooraf is niet nodig. MongoDB Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.
Hoe lang duurt de les “Regex-queries en patroonherkenning”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over MongoDB Academy?
Ja. Elke les over MongoDB Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- Vergelijkingsoperatoren: $eq, $gt, $lt, $in
- Logische operatoren: $and, $or, $nor, $not
- Elementoperatoren en typecontroles
- Regex-queries en patroonherkenning