Regex-frågor och mönstermatchning
Tillämpa reguljära uttryck på strängfält för flexibla sökningar efter textmönster.
Regex-frågor och mönstermatchning är en gratis lektion i MongoDB Academy på CoddyKit. Detta är lektion 4 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för MongoDB Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i MongoDB Academy innehåller totalt 4 lektioner.
När du behöver mönstermatchning
Ibland behöver du söka efter dokument där ett strängfält innehåller, börjar med eller slutar med ett visst mönster – men du känner inte till det exakta värdet. Enkla likhetsfilter som { name: 'Alice' } matchar bara exakta strängar. Reguljära uttryck (regex) ger dig flexibel mönstermatchning mot strängfält i MongoDB.
MongoDB stöder regex via operatorn $regex eller genom att skicka en JavaScript-regexliteral direkt i ett frågefilter. Båda metoderna fungerar, men syntaxen för att ange alternativ som skiftlägesokänslighet skiljer sig något.
Grundläggande regex-syntax i MongoDB
Det finns två sätt att använda regex i MongoDB-frågor:
- JS-regexliteral:
{ name: /alice/i }– kompakt syntax där flaggor anges efter det avslutande snedstrecket $regex-operatorn:{ name: { $regex: 'alice', $options: 'i' } }– utförligare, men krävs när den kombineras med andra operatorer
Båda formerna ger identiska resultat. Använd JS-literalsyntax för enkla frågor och formen med operatorn $regex när du behöver bygga mönstret dynamiskt från en strängvariabel eller kombinera det med andra operatorer på samma fält.
// 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-alternativ: i, m, s, x
MongoDB stöder fyra regex-flaggor:
i– Skiftlägesokänslig:/alice/imatchar ”Alice”, ”ALICE” och ”alice”m– Flera rader:^och$matchar början/slutet av varje rad i stället för hela strängens– Punkt matchar allt:.matchar alla tecken, inklusive radbrytningarx– Utökad: blanksteg i mönstret ignoreras (för lättlästa mönster med kommentarer)
Den vanligaste flaggan är i. Flaggan m är användbar vid sökning i flerradiga textfält, till exempel blogginnehåll. Flera flaggor kan kombineras: { $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 bodyFörankringar: börjar med och slutar med
Använd regex-förankringar för att matcha början eller slutet av ett strängfält:
^förankrar matchningen till början:/^Admin/matchar strängar som börjar med ”Admin”$förankrar matchningen till slutet:/\.pdf$/matchar strängar som slutar med ”.pdf”
Ett viktigt prestandafaktum är att ett prefix-regex med cirkumflex (/^prefix/) KAN använda ett vanligt B-trädsindex på fältet – MongoDB kan gå direkt till prefixet i indexet. Det gör prefixsökningar mycket snabbare än sökningar i mitten av strängar. Använd aldrig ett inledande jokertecken (/.*pattern/ eller /pattern/ utan ^) i en stor samling utan ett textindex.
// 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 thisTeckenklasser och kvantifierare
Regex ger dig uttrycksfulla byggstenar för mönster:
.– valfritt tecken (utom radbrytning, såvida inte flaggansär angiven)[abc]– teckenklass: matchar a, b eller c[a-z]– intervall: valfri gemen bokstav\d– valfri siffra (motsvarar[0-9])\w– valfritt ordtecken ([a-zA-Z0-9_])*,+,?– noll eller fler, en eller fler, noll eller en{n},{n,m}– exakt n förekomster, eller mellan n och m förekomster
// 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 kontra textindex: förstå skillnaden
Regex-frågor och MongoDB:s operator $text har olika användningsområden och mycket olika prestandaegenskaper:
- Regex: matchar efter teckenmönster. Fungerar på alla strängfält och kräver inget särskilt index (även om prefixförankringar använder B-trädsindex). Passar för formatvalidering, prefixsökning eller mönstermatchning i små samlingar eller indexerade prefixfrågor.
$text/ textindex: fulltextsökning efter nyckelord med tokenisering, stemming och filtrering av stoppord. Kräver ett textindex. Är mycket snabbare för nyckelordssökningar i stora textfält (artiklar, beskrivningar och kommentarer).
Använd aldrig /.*keyword.*/i i en stor, oindexerad samling – det leder till en fullständig genomsökning och kan vara långsamt.
// 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: säkerhetsrisken
ReDoS (Regular Expression Denial of Service) är en attack där en angripare skapar en indatasträng som får ett dåligt skrivet regex att ta exponentiellt lång tid att utvärdera. Om du skickar användarindata direkt till ett regex utan att escape:a den kan en angripare låsa din databasfråga.
Escape:a alltid användarindata innan du använder den i ett regex genom att ersätta alla särskilda regex-tecken (. * + ? ^ $ { } ( ) [ ] | \ ) med sina escape:ade motsvarigheter. Många bibliotek (till exempel escape-string-regexp i Node.js) gör detta automatiskt. Föredra dessutom $text framför råa regex för sökfält som riktar sig till användare.
// 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 på arrayfält
När du använder ett regex på ett arrayfält kontrollerar MongoDB om något element i arrayen matchar mönstret – samma innehållssemantik som vid likhetsfrågor på arrayer. Det låter dig söka igenom arrayer med taggar, kategorier eller andra strängarrayer utan en särskild operator.
Exempelvis skulle ett dokument med tags: ['node.js', 'mongodb', 'backend'] returneras av { tags: /^mongo/ } eftersom ”mongodb” börjar med ”mongo”. Regex-uttrycket tillämpas på varje element separat.
// 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 });Praktiskt sökexempel
En typisk sökfunktion för e-handel kombinerar regex med andra filter för att ge en kontextuell, skiftlägesokänslig produktsökning. Frågan matchar produktnamn som innehåller söktermen var som helst i strängen och filtrerar efter kategori och lagerstatus.
För små kataloger (under 50 000 produkter) är regex-sökning acceptabel. För större kataloger eller sökning i fullständiga beskrivningar ger Atlas Search (baserat på Lucene) bättre relevansrankning, stemming och prestanda.
// 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);
});Sammanfattning av regex-prestanda
Viktiga regler för regex-prestanda i MongoDB:
- Prefix med
^(/^prefix/): Kan använda ett B-trädsindex. Bäst prestanda för regex. - Skiftlägeskänsligt prefix (
/^prefix/): Utnyttjar indexordningen fullt ut. - Skiftlägesokänsligt prefix (
/^prefix/i): Använder indexet delvis, men är fortfarande mycket snabbare än utan förankring. - Innehåller utan förankring (
/pattern/): Fullständig genomsökning av samlingen – använd i stället ett textindex. - Suffix (
/pattern$/): Fullständig genomsökning av samlingen eller textindex.
Testa med explain('executionStats') om du är osäker och leta efter IXSCAN respektive 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!)Testa regex-mönster före driftsättning
Innan du kör en regex-fråga mot en produktionssamling bör du testa mönstret mot exempeldokument för att verifiera att det matchar det du avser och inte matchar det du inte avser. MongoDB-skalet låter dig testa snabbt med en liten limit(), och JavaScripts String.prototype.test() eller regex-literals låter dig validera mönster i Node.js innan du bäddar in dem i frågor.
Kontrollera även prestandan med explain(): ett regex som kräver en fullständig genomsökning av samlingen bör omvandlas till en textfråga, eller så bör samlingens storlek beaktas. För nya samlingar bör du planera utifrån sökkraven – lägg till textindex från början i stället för att införa dem i efterhand.
// 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');Snabbtest
Testa dina kunskaper om begreppen MongoDB och NoSQL-databaser från den här lektionen.
Sammanfattning av lektionen
I den här lektionen lärde du dig följande: regex-frågor använder /pattern/flags eller operatorn $regex för flexibel mönstermatchning i strängar – den viktigaste flaggan är i för skiftlägesokänslighet; prefixförankrade regex (/^prefix/) kan använda B-trädsindex för effektiva sökningar, medan mönster mitt i strängar kräver fullständiga genomsökningar; och att du alltid ska escape:a användarindata innan du infogar den i ett regex för att förhindra ReDoS-attacker – eller ännu hellre använda operatorn $text med ett textindex för användarriktad sökning. Härnäst går vi vidare till att uppdatera dokument med $set, $unset och andra uppdateringsoperatorer.
Lär dig JavaScript med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 30
- Lektioner
- 120
Vanliga frågor
Är lektionen ”Regex-frågor och mönstermatchning” gratis?
Ja – hela texten till ”Regex-frågor och mönstermatchning” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i MongoDB Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i MongoDB Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Regex-frågor och mönstermatchning”?
Tillämpa reguljära uttryck på strängfält för flexibla sökningar efter textmönster. Ni övar på MongoDB Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig MongoDB Academy?
Du behöver inga förkunskaper. Utbildningen i MongoDB Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 4 av 4.
Hur lång tid tar lektionen ”Regex-frågor och mönstermatchning”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här MongoDB Academy-lektionen?
Ja. Varje MongoDB Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Jämförelseoperatorer: $eq, $gt, $lt, $in
- Logiska operatorer: $and, $or, $nor, $not
- Elementoperatorer och typkontroller
- Regex-frågor och mönstermatchning