$group: aggregera och beräkna totaler
Ni grupperar dokument efter en nyckel och beräknar summor, medelvärden, antal och andra ackumulatorer med $group.
$group: aggregera och beräkna totaler är en gratis lektion i MongoDB Academy på CoddyKit. Detta är lektion 3 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.
Vad gör $group?
Steget $group slår ihop flera indatadokument till färre utdatadokument baserat på en grupperingsnyckel. Dokument som har samma nyckelvärde slås ihop till ett enda utdatadokument, och ackumulatoroperatorer beräknar aggregerade värden för varje grupp. Se det som MongoDBs motsvarighet till SQL-satsen GROUP BY kombinerad med aggregeringsfunktioner som SUM och COUNT.
// Count orders per user
db.orders.aggregate([
{ $group: {
_id: '$userId', // group by userId
orderCount: { $sum: 1 } // count each document as 1
}}
]);
// Output: one doc per unique userId with their order countFältet _id i $group
Varje $group-steg kräver ett _id-fält som definierar grupperingsnyckeln. _id kan vara en fältreferens ('$field'), ett beräknat uttryck, ett objekt med flera fält (för sammansatt gruppering) eller null (för att aggregera hela samlingen till ett dokument). Värdet för _id i utdata är gruppnyckeln.
// Group by single field
{ $group: { _id: '$status' } }
// Group by multiple fields (compound key)
{ $group: { _id: { year: { $year: '$createdAt' }, status: '$status' } } }
// Group all documents into one (grand total)
{ $group: { _id: null, grandTotal: { $sum: '$amount' } } }
// Group by computed expression
{ $group: { _id: { $toLower: '$category' } } }$sum: räkna och summera
$sum är den mest använda ackumulatorn. Ange 1 för att räkna dokument i varje grupp eller en fältreferens för att summera numeriska fältvärden. Du kan också ange ett uttryck som utvärderas till ett tal. $sum ignorerar icke-numeriska värden och saknade fält (de räknas som noll), vilket gör den säker att använda med valfria numeriska fält.
db.sales.aggregate([{
$group: {
_id: '$region',
// Count documents in each group
transactionCount: { $sum: 1 },
// Sum the 'amount' field
totalRevenue: { $sum: '$amount' },
// Sum a computed expression
totalWithTax: { $sum: { $multiply: ['$amount', 1.1] } }
}
}]);$avg, $min, $max
$avg beräknar det aritmetiska medelvärdet, $min hittar det minsta värdet och $max hittar det största värdet bland alla dokument i en grupp. Alla tre fungerar med numeriska värden och även med strängar och datum (för min/max). De ignorerar nullvärden och saknade fältvärden.
db.orders.aggregate([{
$group: {
_id: '$productId',
avgRating: { $avg: '$rating' }, // average rating
minPrice: { $min: '$price' }, // lowest price ever sold
maxPrice: { $max: '$price' }, // highest price ever sold
firstOrder: { $min: '$createdAt' }, // earliest date
latestOrder: { $max: '$createdAt' } // most recent date
}
}]);$count i $group
Även om du vanligtvis räknar genom att använda { $sum: 1 } i ett $group-steg erbjuder MongoDB även ett fristående $count-steg för att räkna det totala antalet dokument i strömmen. $count-steget genererar ett enda dokument med antalet under det fältnamn du anger. Det motsvarar ett $group med _id: null och $sum: 1.
// Count total published articles
db.articles.aggregate([
{ $match: { status: 'published' } },
{ $count: 'totalPublished' } // emits { totalPublished: N }
]);
// Equivalent using $group:
db.articles.aggregate([
{ $match: { status: 'published' } },
{ $group: { _id: null, totalPublished: { $sum: 1 } } }
]);Sammansatta grupperingsnycklar
För att gruppera efter flera fält samtidigt anger du ett objekt som värde för _id. Varje nyckel i objektet blir en del av den sammansatta gruppnyckeln. Utdatadokumenten har ett kapslat _id-objekt. Detta är standardmetoden för att skapa flerdimensionella aggregeringar som 'intäkt per region och månad'.
// Revenue breakdown by region AND year-month
db.sales.aggregate([
{ $group: {
_id: {
region: '$region',
year: { $year: '$saleDate' },
month: { $month: '$saleDate' }
},
revenue: { $sum: '$amount' },
count: { $sum: 1 }
}},
{ $sort: { '_id.year': 1, '_id.month': 1, '_id.region': 1 } }
]);
// Output: { _id: { region: 'EMEA', year: 2024, month: 3 }, revenue: 50000, count: 120 }Samla värden i arrayer med $push
$push-ackumulatorn samlar alla värden från ett fält i de grupperade dokumenten i en array. Detta är användbart för att samla alla order-ID:n för en användare, alla taggar i en kategori eller alla användar-ID:n som köpt en produkt. Resultatarrayen kan innehålla dubbletter; använd i stället $addToSet för att samla unika värden.
// Collect all order IDs per user
db.orders.aggregate([{
$group: {
_id: '$userId',
orderIds: { $push: '$_id' }, // all order IDs for this user
amounts: { $push: '$amount' }, // all amounts
// Collect whole sub-documents
orderSummaries: {
$push: { orderId: '$_id', amount: '$amount', status: '$status' }
}
}
}]);Ackumulatorerna $first och $last
$first och $last returnerar det första respektive sista fältvärdet som påträffas per grupp, i den ordning dokumenten bearbetas. Eftersom MongoDB inte garanterar dokumentordningen om du inte sorterar först bör du lägga till ett $sort-steg före $group-steget för att göra $first/$last meningsfulla, till exempel för 'första beställningsdatumet per kund'.
// Most and least recent order per customer
db.orders.aggregate([
{ $sort: { createdAt: 1 } }, // sort BEFORE group for meaningful first/last
{ $group: {
_id: '$customerId',
firstOrder: { $first: '$createdAt' },
firstOrderId: { $first: '$_id' },
lastOrder: { $last: '$createdAt' },
lastAmount: { $last: '$amount' }
}}
]);Gruppering efter beräknade uttryck
$group:s _id kan vara vilket uttryck som helst, inte bara en fältreferens. Du kan gruppera efter ett avkortat datum (år-vecka), en beräknad kategori, ett matematiskt intervall eller en delsträng av ett fält. På så sätt kan du skapa flexibla analytiska grupperingar utan att behöva förberäknade intervallfält i de lagrade dokumenten.
// Group orders by price bucket: 0-99, 100-499, 500+
db.orders.aggregate([{
$group: {
_id: {
$switch: {
branches: [
{ case: { $lt: ['$amount', 100] }, then: 'small' },
{ case: { $lt: ['$amount', 500] }, then: 'medium' }
],
default: 'large'
}
},
count: { $sum: 1 },
totalRevenue: { $sum: '$amount' }
}
}]);Gruppering i två steg
Komplexa analyser kräver ofta två $group-steg i följd: det första grupperar på detaljnivå (till exempel per användare), och det andra grupperar resultaten från det första steget på en högre nivå (till exempel per region). Detta mönster med två steg undviker kapslade $group-uttryck och ger renare och mer lättbegripliga pipelines.
// Average orders per user, per region
db.orders.aggregate([
// Stage 1: sum per user
{ $group: {
_id: { userId: '$userId', region: '$region' },
userOrderCount: { $sum: 1 }
}},
// Stage 2: average of those sums, per region
{ $group: {
_id: '$_id.region',
avgOrdersPerUser: { $avg: '$userOrderCount' },
uniqueUsers: { $sum: 1 }
}}
]);$group-prestanda: inget index tillgängligt
Till skillnad från $match kan steget $group inte använda ett index – det måste bearbeta alla dokument som skickas till det. Därför är det avgörande att minska indatamängden med ett tidigt $match. För mycket stora datamängder där $group använder för mycket minne kan allowDiskUse: true anges för att skriva överflödig data till disk. Ett alternativ är att beräkna och lagra aggregerade värden i förväg (Computed Pattern), vilket undviker gruppering vid körning i tidskritiska flöden.
// Allow disk use for large aggregations
db.orders.aggregate(
[
{ $match: { year: 2024 } },
{ $group: { _id: '$productId', revenue: { $sum: '$amount' } } },
{ $sort: { revenue: -1 } }
],
{ allowDiskUse: true } // spill to disk if memory limit exceeded
);Snabb kontroll
Testa er förståelse av steget $group i aggregeringspipelinen.
Sammanfattning av lektionen
I den här lektionen har ni lärt er att $group slår samman dokument utifrån en nyckel som definieras i fältet _id, att ackumulatorer som $sum, $avg, $min, $max, $push beräknar aggregerade värden per grupp och att gruppering i två steg möjliggör hierarkisk analys. Nästa steg är att utforska $sort, $limit och $skip för att ordna och paginera aggregeringsresultat.
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 ”$group: aggregera och beräkna totaler” gratis?
Ja – hela texten till ”$group: aggregera och beräkna totaler” 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 ”$group: aggregera och beräkna totaler”?
Ni grupperar dokument efter en nyckel och beräknar summor, medelvärden, antal och andra ackumulatorer med $group. 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 3 av 4.
Hur lång tid tar lektionen ”$group: aggregera och beräkna totaler”?
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
- Pipelinkoncept: steg, operatorer och uttryck
- $match och $project: filtrera och omforma
- $group: aggregera och beräkna totaler
- $sort, $limit och $skip i pipelinen