Razumevanje Agregacionog Cjevovoda u MongoDB-u
Agregacioni cjevovod predstavlja preporučeni metod za izvršavanje kompleksnih upita unutar MongoDB baze podataka. Ako ste ranije koristili MapReduce u MongoDB-u, prelazak na agregacioni cjevovod bi bio mudra odluka, s obzirom na njegovu efikasnost pri obradi podataka.
Šta je agregacija u MongoDB-u i kako funkcioniše?
Agregacioni cjevovod je proces obrade podataka u više koraka, koji se koristi za izvršavanje naprednih upita u MongoDB-u. Podaci prolaze kroz različite faze, koje se nazivaju fazama cjevovoda. Rezultati jedne faze se mogu koristiti kao ulaz za sledeću fazu, omogućavajući složenu transformaciju podataka.
Na primer, rezultat faze filtriranja (match) se može proslediti u fazu sortiranja, sve dok se ne postigne željeni rezultat.
Svaka faza agregacionog cjevovoda koristi MongoDB operator i generiše transformisane dokumente. U zavisnosti od upita, pojedinačne faze se mogu ponavljati unutar cjevovoda. Na primer, faze operacija poput $count ili $sort se mogu koristiti više puta.
Faze Agregacionog Cjevovoda
Agregacioni cjevovod propušta podatke kroz nekoliko faza unutar jednog upita. Postoji više faza, a njihove detalje možete naći u MongoDB dokumentaciji.
U nastavku ćemo predstaviti neke od najčešće korišćenih faza.
Faza $match
Ova faza omogućava definisanje uslova filtriranja pre drugih faza agregacije. Koristi se za selekciju relevantnih podataka za dalju obradu.
Faza $group
Faza grupisanja deli podatke u različite grupe na osnovu određenih kriterijuma, koristeći parove ključ-vrednost. Svaka grupa se predstavlja ključem u izlaznom dokumentu.
Na primer, posmatrajmo sledeći uzorak podataka o prodaji:
Uz pomoć agregacionog cjevovoda, možete izračunati ukupan broj prodaja i najveću prodaju za svaki odsek proizvoda:
{
$group: {
_id: $Section,
total_sales_count: {$sum : $Sold},
top_sales: {$max: $Amount},
}
}
Par _id: $Section
grupiše izlazne dokumente po odsecima. Definisanjem polja total_sales_count
i top_sales
, MongoDB kreira nove ključeve na osnovu operacija definisanih od strane agregatora, kao što su $sum
, $min
, $max
ili $avg
.
Faza $skip
Faza $skip služi za preskakanje određenog broja dokumenata u izlaznom skupu, obično se koristi nakon faze grupisanja. Na primer, ako očekujete dva izlazna dokumenta i preskočite jedan, agregacija će vratiti samo drugi dokument.
Za dodavanje faze preskakanja, umetnite operaciju $skip
u agregacioni cjevovod:
...,
{
$skip: 1
},
Faza $sort
Faza sortiranja omogućava uređivanje podataka u rastućem ili opadajućem redosledu. Možemo sortirati podatke iz prethodnog primera upita u opadajućem redosledu, kako bismo utvrdili koji odsek ima najveću prodaju.
Dodajte operator $sort
u prethodni upit:
...,
{
$sort: {top_sales: -1}
},
Faza $limit
Operacija limitiranja pomaže u smanjenju broja izlaznih dokumenata koje agregacioni cjevovod vraća. Koristite operator $limit
da biste dobili odsek sa najvećom prodajom iz prethodne faze:
...,
{
$sort: {top_sales: -1}
},{"$limit": 1}
Gornji kod vraća samo prvi dokument, koji predstavlja odsek sa najvećom prodajom, s obzirom da se nalazi na vrhu sortiranog izlaza.
Faza $project
Faza $project
omogućava oblikovanje izlaznog dokumenta po želji. Možete odrediti koja polja će biti uključena u izlaz i prilagoditi njihova imena koristeći operator $project
.
Na primer, izlaz bez faze $project
izgleda ovako:
Pogledajmo kako izlaz izgleda nakon primene faze $project
. Za dodavanje $project
u cjevovod:
...,{
"$project": {
"_id": 0,
"Section": "$_id",
"TotalSold": "$total_sales_count",
"TopSale": "$top_sales",}
}
S obzirom da smo prethodno grupisali podatke po odsecima proizvoda, gornji kod uključuje svaki odsek proizvoda u izlaznom dokumentu. Takođe obezbeđuje da se ukupan broj prodaja i najveća prodaja prikažu kao TotalSold
i TopSale
.
Konačni rezultat je mnogo pregledniji u odnosu na prethodni:
Faza $unwind
Faza $unwind
razlaže niz unutar dokumenta u pojedinačne dokumente. Razmotrite sledeće podatke o porudžbinama:
Koristite fazu $unwind
za dekonstrukciju niza stavki pre primene drugih faza agregacije. Na primer, razmotavanje niza stavki je korisno ako želite izračunati ukupan prihod za svaki proizvod:
db.Orders.aggregate(
[
{
"$unwind": "$items"
},
{
"$group": {
"_id": "$items.product",
"total_revenue": { "$sum": { "$multiply": ["$items.quantity", "$items.price"] } }
}
},
{
"$sort": { "total_revenue": -1 }
},{
"$project": {
"_id": 0,
"Product": "$_id",
"TotalRevenue": "$total_revenue",}
}
])
Evo rezultata gornjeg agregacionog upita:
Kako kreirati agregacioni cjevovod u MongoDB-u
Iako agregacioni cjevovod uključuje nekoliko operacija, ranije predstavljene faze vam daju ideju kako ih primeniti u cjevovodu, zajedno sa osnovnim upitom za svaku fazu.
Koristeći prethodni primer podataka o prodaji, prikazaćemo neke od gore navedenih faza u jednom komadu radi šireg razumevanja agregacionog cjevovoda:
db.sales.aggregate([{
"$match": {
"Sold": { "$gte": 5 }
}
},{
"$group": {
"_id": "$Section",
"total_sales_count": { "$sum": "$Sold" },
"top_sales": { "$max": "$Amount" },
}},
{
"$sort": { "top_sales": -1 }
},{"$skip": 0},
{
"$project": {
"_id": 0,
"Section": "$_id",
"TotalSold": "$total_sales_count",
"TopSale": "$top_sales",}
}
])
Konačan rezultat izgleda kao nešto što ste već videli:
Agregacioni Cjevovod protiv MapReduce
Pre nego što je zastareo u MongoDB 5.0, konvencionalni način za agregaciju podataka u MongoDB-u bio je preko MapReduce. Iako MapReduce ima šire primene izvan MongoDB-a, manje je efikasan od agregacionog cjevovoda. Razlog je taj što zahteva skriptovanje treće strane za pisanje map i reduce funkcija odvojeno.
Sa druge strane, agregacioni cjevovod je specifičan samo za MongoDB. Pruža čistiji i efikasniji način za izvršavanje kompleksnih upita. Pored jednostavnosti i skalabilnosti upita, raznovrsne faze cjevovoda omogućavaju fleksibilan i prilagodljiv izlaz.
Postoji mnogo razlika između agregacionog cjevovoda i MapReduce. Možete ih uočiti u procesu prelaska sa MapReduce na agregacioni cjevovod.
Učinite upite nad velikim skupovima podataka efikasnim u MongoDB-u
Vaš upit mora biti što efikasniji ako želite pokretati detaljne proračune nad kompleksnim podacima u MongoDB-u. Agregacioni cjevovod je idealan za napredno postavljanje upita. Umesto da manipulišete podacima kroz odvojene operacije, što često smanjuje performanse, agregacija vam omogućava da sve operacije objedinite u jedan cjevovod i izvršite ih istovremeno.
Iako je agregacioni cjevovod efikasniji od MapReduce, možete dodatno ubrzati agregaciju indeksiranjem podataka. To ograničava količinu podataka koju MongoDB mora skenirati tokom svake faze agregacije.