$match og $project: Filtrere og omforme
Deltakerne vil plassere $match tidlig i pipelinen for bedre ytelse og bruke $project til å gi felt nye navn og beregne nye felt.
$match og $project: Filtrere og omforme er en gratis leksjon i MongoDB Academy på CoddyKit. Dette er leksjon 2 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i MongoDB Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i MongoDB Academy inneholder totalt 4 leksjoner.
$match-stagen
$match-stagen tilsvarer et find()-filter i en aggregation pipeline. Den godtar samme spørringssyntaks – likhetssjekker, sammenligningsoperatorer, logiske operatorer, $regex og $elemMatch – og filtrerer dokumentstrømmen ved å fjerne dokumenter som ikke samsvarer. Dokumenter som består, sendes videre til neste stage; de øvrige forkastes.
// $match uses the same syntax as find() filters
db.orders.aggregate([
{ $match: {
status: 'completed',
amount: { $gte: 100 },
createdAt: { $gte: new Date('2024-01-01') }
}}
]);
// Only orders matching ALL three conditions pass throughPlasser $match først for å bruke indekser
Når $match er den første stagen i pipelinen, kan MongoDB bruke en indeks til å utføre filteret – akkurat som med en find()-spørring. Hvis $match kommer etter andre stages, går indeksfordelen tapt fordi spørringsplanleggeren bare kan flytte indeksbruken til den første stagen. Dette er den viktigste ytelsesregelen ved utforming av aggregation pipelines.
// GOOD: $match first -> uses index on userId
db.orders.aggregate([
{ $match: { userId: 'u1', status: 'active' } }, // index used here
{ $group: { _id: '$productId', count: { $sum: 1 } } }
]);
// BAD: $match after $group -> full collection scan
db.orders.aggregate([
{ $group: { _id: '$productId', count: { $sum: 1 } } },
{ $match: { userId: 'u1' } } // too late for index
]);Bruke $match med $text
Operatoren $text for fulltekstsøk kan bare brukes i $match, og bare når den er den første stagen i pipelinen. Begrensningen skyldes at MongoDB må sende tekstsøket til tekstindeksen, noe som skjer på spørringsplannivå før noen stages-transformasjoner utføres. Etter at $match har filtrert på tekst, kan De projisere tekstscoren og sortere etter relevans i påfølgende stages.
db.articles.aggregate([
// $text in $match MUST be the first stage
{ $match: { $text: { $search: 'mongodb aggregation' } } },
{ $addFields: { score: { $meta: 'textScore' } } },
{ $sort: { score: -1 } },
{ $limit: 5 }
]);$project-stagen
$project-stagen omformer dokumenter: De kan inkludere eller ekskludere felt, gi felt nye navn og beregne helt nye felt ved hjelp av uttrykksoperatorer. Den sender ett utdatadokument for hvert inndatadokument (i motsetning til $group, som slår sammen mange dokumenter til ett). En $project-stage brukes ofte til å redusere dokumentene før kostbare stages, eller til å klargjøre formen på det endelige resultatet.
db.users.aggregate([
{ $project: {
_id: 0, // exclude _id
name: 1, // include name
email: 1, // include email
// Exclude password - never send to client!
// (fields not listed are excluded when any field is included)
}}
]);Inkludering kontra ekskludering i $project
Som ved projeksjoner i find() kan $project ikke blande inkludering og ekskludering i samme stage – med unntak av _id, som alltid kan ekskluderes eksplisitt, også i en inkluderende projeksjon. Sett et felt til 1 for å inkludere det, til 0 for å ekskludere det, eller bruk et uttrykk for å beregne og inkludere det. Felt som ikke er nevnt i en inkluderende projeksjon, fjernes.
// Inclusion mode: list what you WANT
db.products.aggregate([{
$project: {
_id: 0, // OK to exclude _id in inclusion mode
name: 1,
price: 1
}
}]);
// Exclusion mode: list what you DON'T want
db.products.aggregate([{
$project: {
password: 0,
__v: 0
}
}]);
// Cannot mix: { name: 1, password: 0 } is an error (except _id)Beregne nye felt i $project
Den virkelige styrken til $project ligger i å beregne nye avledede felt ved hjelp av uttrykksoperatorer. De kan gi et felt nytt navn ved å tilordne det en feltreferanse, utføre aritmetikk, formatere strenger eller bruke betingelser – alt på serversiden, uten å endre de lagrede dokumentene. De beregnede feltene finnes bare i pipeline-resultatet; de underliggende dokumentene forblir uendret.
db.invoices.aggregate([
{ $project: {
invoiceNumber: '$_id', // rename _id to invoiceNumber
clientName: '$client.name', // flatten nested field
subtotal: 1,
tax: { $multiply: ['$subtotal', 0.08] }, // compute tax
total: { $add: ['$subtotal', { $multiply: ['$subtotal', 0.08] }] },
issued: { $dateToString: { format: '%Y-%m-%d', date: '$createdAt' } }
}}
]);Gi felt nye navn og bygg inn felt
De kan bruke $project til å strukturere dokumentformen på nytt: flate ut nestede felt til toppnivået eller samle flate felt i et nestet underdokument. Dette er nyttig for å tilpasse MongoDB-resultatet til et API-skjema som skiller seg fra strukturen i det lagrede dokumentet, uten å endre hvordan dataene lagres.
// Document: { firstName: 'Alice', lastName: 'Smith', age: 30 }
// API wants: { name: { first, last }, age }
db.users.aggregate([{
$project: {
_id: 0,
name: {
first: '$firstName', // group into nested object
last: '$lastName'
},
age: 1
}
}]);
// Output: { name: { first: 'Alice', last: 'Smith' }, age: 30 }Bruke $project med arrayer
$project støtter array-uttrykk for å transformere eller filtrere arrayer i dokumenter. De kan bruke $map til å transformere hvert element, $filter til å velge elementer som oppfyller en betingelse, $slice til å hente et delutvalg eller $arrayElemAt til å få tilgang til en bestemt indeks. Disse operasjonene kjøres på serversiden på hele arrayen uten at flere pipeline-stages er nødvendige.
db.articles.aggregate([{
$project: {
title: 1,
// Keep only published tags
activeTags: {
$filter: {
input: '$tags',
as: 'tag',
cond: { $eq: ['$$tag.active', true] }
}
},
// First author only
leadAuthor: { $arrayElemAt: ['$authors', 0] },
// Uppercase each tag name
upperTags: { $map: { input: '$tags', as: 't', in: { $toUpper: '$$t' } } }
}
}]);Flere $match-stages
De kan bruke flere $match-stages i samme pipeline. Et vanlig mønster er å bruke $match tidlig for å utnytte en indeks, deretter bruke $group eller $project til å beregne nye felt, og så bruke en andre $match til å filtrere på de beregnede verdiene. Den første $match-stagen får fordel av indeksbruk; den andre filtrerer det beregnede resultatsettet.
db.orders.aggregate([
// First $match: uses index on userId
{ $match: { userId: 'u1' } },
// Compute revenue per product
{ $group: { _id: '$productId', revenue: { $sum: '$amount' } } },
// Second $match: filter computed revenue (no index possible here)
{ $match: { revenue: { $gte: 500 } } },
{ $sort: { revenue: -1 } }
]);Når bør De bruke $addFields i stedet for $project
En vanlig utfordring med $project er at De i inkluderingsmodus må liste opp alle feltene De vil beholde. Hvis De bare vil legge til nye felt uten å fjerne eksisterende felt, bør De i stedet bruke $addFields (eller aliaset $set). $addFields viderefører alle eksisterende felt og legger bare til eller overskriver de angitte feltene – langt mindre omstendelig når De enkelt skal legge til beregnede felt.
// $project: must list ALL fields you want to keep
db.users.aggregate([{ $project: { name: 1, email: 1, age: 1,
ageGroup: { $cond: { if: { $lt: ['$age', 18] }, then: 'minor', else: 'adult' } }
}}]);
// $addFields: keeps all fields, just adds ageGroup
db.users.aggregate([{ $addFields: {
ageGroup: { $cond: { if: { $lt: ['$age', 18] }, then: 'minor', else: 'adult' } }
}}]);
// All original fields (name, email, age, etc.) are preservedPipeline-ytelse: $project tidlig
Ved å plassere en $project-stage tidlig i pipelinen for å fjerne unødvendige felt reduseres minnet og båndbredden som brukes av påfølgende stages. Hvis senere stages ikke trenger en stor innebygd array eller et langt tekstfelt, kan De ekskludere dem med en tidlig $project eller $unset. Dette har særlig stor effekt når dokumentene er store og pipelinen har mange stages.
db.articles.aggregate([
{ $match: { status: 'published' } },
// Trim large fields early before expensive stages
{ $project: {
title: 1,
authorId: 1,
publishedAt: 1,
categoryId: 1,
// Exclude: body (could be 50KB), rawHtml (100KB)
// This reduces memory in all subsequent stages
}},
{ $lookup: { from: 'authors', localField: 'authorId', foreignField: '_id', as: 'author' } },
{ $sort: { publishedAt: -1 } },
{ $limit: 20 }
]);Kunnskapssjekk
Test forståelsen Deres av $match og $project i aggregation pipelinen.
Oppsummering av leksjonen
I denne leksjonen lærte De at $match filtrerer dokumentstrømmen ved hjelp av samme spørringssyntaks som find(), og bør plasseres først for å utnytte indekser, at $project omformer dokumenter ved å inkludere, ekskludere og beregne felt, og at $addFields er bedre når De bare vil legge til felt uten å liste opp alle eksisterende felt. Deretter tar vi for oss $group for aggregering og beregning av totaler.
Lær deg JavaScript med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 30
- Leksjoner
- 120
Ofte stilte spørsmål
Er leksjonen «$match og $project: Filtrere og omforme» gratis?
Ja – hele teksten i «$match og $project: Filtrere og omforme» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av MongoDB Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i MongoDB Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «$match og $project: Filtrere og omforme»?
Deltakerne vil plassere $match tidlig i pipelinen for bedre ytelse og bruke $project til å gi felt nye navn og beregne nye felt. Du øver på MongoDB Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med MongoDB Academy?
Ingen tidligere erfaring er nødvendig. MongoDB Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.
Hvor lang tid tar leksjonen «$match og $project: Filtrere og omforme»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne MongoDB Academy-leksjonen?
Ja. Alle MongoDB Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Pipeline-konsepter: Trinn, operatorer og uttrykk
- $match og $project: Filtrere og omforme
- $group: Aggregere og beregne totaler
- $sort, $limit og $skip i pipelinen