MongoDB Academy · Oppitunti

$group: Koostaminen ja summien laskeminen

Oppijat ryhmittelevät dokumentteja avaimen perusteella ja laskevat summia, keskiarvoja, lukumääriä ja muita koostearvoja $group-operaattorilla.

Oppitunti 3/413 vaihetta

$group: Koostaminen ja summien laskeminen on ilmainen MongoDB Academy-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu MongoDB Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. MongoDB Academy-kurssilla on yhteensä 4 oppituntia.

Mitä $group tekee?

$group-vaihe yhdistää useita syötedokumentteja pienemmäksi määräksi tulosdokumentteja ryhmittelyavaimen perusteella. Dokumentit, joilla on sama avaimen arvo, yhdistetään yhdeksi tulosdokumentiksi, ja akkumulaattorioperaattorit laskevat kullekin ryhmälle koontiarvot. Ajattele sitä MongoDB:n vastineena SQL:n GROUP BY-lausekkeelle yhdessä koontifunktioiden, kuten SUM ja COUNT, kanssa.

// 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 count

_id-kenttä $group-vaiheessa

Jokainen $group-vaihe edellyttää _id-kenttää, joka määrittää ryhmittelyavaimen. _id voi olla kenttäviite ('$field'), laskettu lauseke, useita kenttiä sisältävä objekti (yhdistelmäryhmittelyä varten) tai null (kokoelman kokoamiseksi yhdeksi dokumentiksi). Tulosteen _id-arvo on ryhmittelyavain.

// 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: laskeminen ja summien laskeminen

$sum on yleisimmin käytetty akkumulaattori. Välitä sille 1, kun haluat laskea kunkin ryhmän dokumentit, tai kenttäviite, kun haluat summata numeerisen kentän arvot. Voit välittää sille myös lausekkeen, jonka tulos on luku. $sum ohittaa ei-numeeriset arvot ja puuttuvat kentät (ne lasketaan nollaksi), joten sitä on turvallista käyttää valinnaisissa numeerisissa kentissä.

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 laskee aritmeettisen keskiarvon, $min etsii pienimmän arvon ja $max suurimman arvon ryhmän kaikista dokumenteista. Kaikki kolme toimivat numeerisilla arvoilla sekä merkkijonoilla ja päivämäärillä ($min- ja $max-operaattoreiden tapauksessa). Ne ohittavat null-arvot ja puuttuvien kenttien arvot.

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 $group-vaiheessa

Vaikka yleensä lasket dokumentit käyttämällä { $sum: 1 }-lauseketta $group-vaiheessa, MongoDB tarjoaa myös erillisen $count-vaiheen putken dokumenttien kokonaismäärän laskemiseen. $count-vaihe tuottaa yhden dokumentin, jonka määrittämäsi kenttä sisältää lukumäärän. Se vastaa $group-vaihetta, jossa käytetään arvoja _id: null ja $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 } } }
]);

Yhdistelmäryhmittelyavaimet

Kun haluat ryhmitellä useiden kenttien perusteella samanaikaisesti, välitä objekti _id-arvoksi. Jokaisesta objektin avaimesta tulee osa yhdistelmäryhmittelyavainta. Tulosdokumenttien _id on sisäkkäinen objekti. Tämä on vakiotapa tuottaa moniulotteisia aggregaatioita, kuten ”tuotto alueen ja kuukauden mukaan”.

// 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 }

Taulukoihin kerääminen $push-operaattorilla

$push-akkumulaattori kerää kentän kaikki arvot ryhmiteltyjen dokumenttien joukosta taulukoksi. Tämä on hyödyllistä, kun haluat kerätä kaikki käyttäjän tilauskoodit, luokan kaikki tunnisteet tai kaikki tuotteen ostaneiden käyttäjien tunnisteet. Tulostaulukko voi sisältää kaksoiskappaleita; käytä sen sijaan $addToSet-operaattoria, kun haluat kerätä yksilölliset arvot.

// 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' }
    }
  }
}]);

$first- ja $last-akkumulaattorit

$first ja $last palauttavat kunkin ryhmän ensimmäisen ja viimeisen käsitellyn kenttäarvon siinä järjestyksessä, jossa dokumentit käsitellään. Koska MongoDB ei takaa dokumenttien järjestystä, ellet lajittele niitä ensin, sinun kannattaa lisätä $sort-vaihe ennen $group-vaihetta, jotta $first- ja $last-operaattoreiden tuloksilla on merkitys — esimerkiksi ”asiakkaan ensimmäinen tilauspäivä”.

// 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' }
  }}
]);

Ryhmittely laskettujen lausekkeiden perusteella

$group-vaiheen _id voi olla mikä tahansa lauseke, ei vain kenttäviite. Voit ryhmitellä katkaistun päivämäärän (vuosi–viikko), lasketun luokan, matemaattisen välin tai kentän osamerkkijonon perusteella. Näin voit luoda joustavia analyyttisiä ryhmittelyjä ilman, että tallennettuihin dokumentteihin tarvitaan valmiiksi laskettuja ryhmittelykenttiä.

// 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' }
  }
}]);

Kaksivaiheinen ryhmittely

Monimutkaiset analyysit edellyttävät usein kahta peräkkäistä $group-vaihetta: ensimmäinen ryhmittelee yksityiskohtaisella tasolla (esimerkiksi käyttäjän mukaan), ja toinen ryhmittelee ensimmäisen vaiheen tulokset ylemmällä tasolla (esimerkiksi alueen mukaan). Tämä kaksivaiheinen malli välttää sisäkkäiset $group-lausekkeet ja tuottaa selkeämpiä ja helpommin ymmärrettäviä putkia.

// 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-suorituskyky: indeksiä ei ole käytettävissä

Toisin kuin $match-vaihe, $group-vaihe ei voi käyttää indeksiä – sen on käsiteltävä kaikki sille välitetyt dokumentit. Siksi syötteen pienentäminen aikaisella $match-vaiheella on ratkaisevan tärkeää. Jos tietojoukot ovat erittäin suuria ja $group käyttää liikaa muistia, määritä allowDiskUse: true, jotta tietoja voidaan siirtää levylle. Vaihtoehtoisesti arvojen aggregointi etukäteen ja tallentaminen (Computed Pattern) välttää ryhmittelyn suorituksen aikana usein käytetyillä suorituspoluilla.

// 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
);

Pikatarkistus

Testaa, miten hyvin ymmärrät koostamisputken $group-vaiheen.

Oppitunnin kertaus

Tässä oppitunnissa opit, että $group yhdistää dokumentit _id-kentässä määritetyn avaimen perusteella, akut kuten $sum, $avg, $min, $max ja $push laskevat koontiarvoja ryhmäkohtaisesti ja kaksivaiheinen ryhmittely mahdollistaa hierarkkisen analytiikan. Seuraavaksi tutustumme vaiheisiin $sort, $limit ja $skip, joilla koostamistulokset järjestetään ja sivutetaan.

Aloita maksutta

Opi JavaScript tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
30
Oppitunnit
120

Usein kysytyt kysymykset

Onko oppitunti ”$group: Koostaminen ja summien laskeminen” ilmainen?

Kyllä – oppitunnin ”$group: Koostaminen ja summien laskeminen” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko MongoDB Academy-kurssin, päivitä CoddyKit PROhon. MongoDB Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”$group: Koostaminen ja summien laskeminen”?

Oppijat ryhmittelevät dokumentteja avaimen perusteella ja laskevat summia, keskiarvoja, lukumääriä ja muita koostearvoja $group-operaattorilla. Harjoittelet MongoDB Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni MongoDB Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin MongoDB Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.

Kuinka kauan ”$group: Koostaminen ja summien laskeminen”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä MongoDB Academy-oppitunnilla?

Kyllä. Jokainen MongoDB Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Putkikäsittelyn perusteet: vaiheet, operaattorit ja lausekkeet
  2. $match ja $project: Suodatus ja rakenteen muokkaus
  3. $group: Koostaminen ja summien laskeminen
  4. $sort, $limit ja $skip putkikäsittelyssä
← Takaisin: MongoDB Academy