You are on page 1of 39

Operacije agregacije u MongoDB

Opercije agregacije
• MongoDB posjeduje operacije agregacije koje obrađuju podatke i
vraćaju izračunate rezultate
• Operacije agregacije grupišu vrednosti iz više dokumenata i onda
primenjuju različite operacije nad grupom dokumenata kako bi vratili
jedan rezultat
• Dobijeni rezultat je novi JSON dokument koji može imati totalno
drugačiju strukturu od ulaznih dokumenata
• MongoDB pruža tri načina za agregaciju dokumenata:
– specijalni metodi za agregiranje
– pipeline-ovanje više naredbi
– map-reduce algoritam
Specijalni metodi za agregiranje

• Ove operacije vrše agregiranje nad jednom kolekcijom


• Primeri takvih operacija
– distinct
– count
Specijalni metodi za agregiranje

• Operacija count
– Prebrojava i vraća broj dokumenata koji zadovoljavaju neki
uslov
– Sintaksa
db.collection.count(query, options)
- parametar query definiše uslov koji dokumenti treba da zadovolje
- parametar options definiše dodatna ograničenja i nije obavezan
– operacija count() je identična sa
db.collection.find(query).count()
Specijalni metodi za agregiranje

• Operacija distinct
– Pronalzi različite vrednosti za zadato polje i vraća rezultat kao
niz vrednosti
– Sintaksa
db.collection.distinct(field, query, options)
- parametar field definiše polje za koje se traže različite vrednosti
- query definiše skup dokumenata nad kojim se opercija izvodi
- options definiše dodanta ograničenja koja se odnose na tražene
dokumente
Pipeline-ovanje

• Ideja ovog principa je da dokumenti prolaze kroz različite


faze, pri čemu se dokumenti transformišu i kao takvi ulaze
u sledeću fazu dok se ne dobije agregirani rezultat
• Ovo je alternativa map - reduce algoritmu
• MongoDB ima operaciju aggregate koja kao parametar
sadrži operatore
• MongoDB sadrži ugrađene operatore koji se mogu
ulančavati
Pipeline-ovanje

• Sintaksa operacije aggregate


db.collection.aggregate(pipeline, options)
- pipeline je niz operatora koji se ulančavaju i redom primejuju na
dokumentima
- options je opcionalni parametar koji detaljnije opisuje agregaciju
Operatori za agregiranje

• Neki od korisnih operatora:


– $match -> filtrira ulazne dokumente tako da samo oni koji zadovoljavaju
kriterijum mogu proći u sledeću fazu obrade
– $project -> menja svaki dokument koji stiže tako što dodaje ili izbacuje
neka polja. Za jedan ulazni dokument dobija se jedan izlazni dokument
– $group -> grupiše ulazne dokumente po nekom kriterijumu i primenjuje
izraz za akumuliranje na pojedinačnoj grupi
– $sort -> menja redosled dokumenata prema određenom kriterijumu.
Dokumenti ostaju isti, samo se redosled obrade menja.
Pipeline-ovanje

• Primer JSON dokumenta

{
"_id": "10280",
"city": "NEW YORK",
"state": "NY",
"pop": 5574,
"loc": [-74.016323, 40.710537]
}
Pipeline-ovanje

• Zadatak1. Vratite države koje imaju preko 10 miliona


stanovnika

db.zipcodes.aggregate( [
{ $group:{ _id: "$state", totalPop: { $sum: "$pop" } } },
{ $match:{ totalPop: { $gte: 10000000 } } }
])
SELECT state, SUM(pop) AS totalPop
FROM zipcodes
GROUP BY state
HAVING totalPop >= 10000000
Pipeline-ovanje

• Zadatak 2.Vratite prosečan broj stanovnika u gradovima


za svaku državu

db.zipcodes.aggregate( [
{ $group: { _id: { state: "$state", city: "$city" }, pop: { $sum: "$pop" } } },
{ $group: { _id: "$_id.state", avgCityPop: { $avg: "$pop" } } }
])
Map-Reduce algoritam
• Map – reduce algoritam je način kako da se organizuje obrada
podataka na klasteru a da se pri tome smanji komunikacija
između čvorova u klasteru
• Ideja je potekla od Google i najčešće korišćena implementacija
ovog algoritma je deo Hadoop sistema, mada i neke druge nosql
baze imaju svoju implementaciju
• Ime map-reduce potiče iz funkcionalnih jezika koji imaju map-
reduce operacije nad kolekcijama
• Map reduce algoritmi se mogu pisati u bilo kom programskom
jeziku, međutim postoje i alati koji pojednostavljuju pisanje map i
reduce funkcija kao što je Apache Pig ili Apache Hive
Osnovna ideja

• Posmatrajmo bazu koja sadrži narudžbine i kupce kao


agregate.
• Svaka narudžbina ima listu proizvoda koji su naručeni.
Svaki proizvod ima id proizvoda, količinu i cenu
• Baza je raspoređena na nekoliko čvorova i potrebno je
dobiti informacije o proizvodu i njegovoj ukupnoj prodaji
za sedam dana
• Ovakav upit ne odgovara našoj strukturi agregata i ovo je
odličan primer za primenu map-reduce algoritma
Osnovna ideja
• Map-reduce algoritam se sastoji od dva koraka:
1. map korak – map je funkcija čiji ulaz je pojedinačni agregat a
izlaz je lista ključ –vrednost parova
U našem primeru ulaz je json dokument narudžbine, a izlaz je
lista poručenih proizvoda , gde je ključ id proizvoda a vrednosti su
količina i cena
primena map funkcije je nezavisna od čvora do čvora, tako da se
ova operacija može izvoditi paralelno na klasteru
2. reduce korak – reduce funkcija kao ulaz uzima listu ključ-
vrednost parova koji imaju isti ključ i vraća jedan ključ-vrednost
objekat gde su svi pojedinačni objekti agregirani
Osnovna ideja

• Map korak
Osnovna ideja

• Reduce korak
Optimizacija Map-Reduce algoritma

• Tehnika particionisanja
– ideja je da se rezultati map funkcije grupišu na jednom čvoru i
da se pošalju reduce funkciji.
– tačnije pošto reduce funkcija radi samo sa jednim ključem, tu
grupu će paralelno obrađivati više reduce funkcija čiji će se
rezultati na kraju skupiti
Optimizacija Map-Reduce algoritma
Optimizacija Map-Reduce algoritma

• Tehnika kombinovanja
– cilj je da se smanji količina podataka koja se šalje sa čvora na
čvor izmeđi koraka map i reduce
– s obzirom da se na jednom čvoru može naći više ključ-vrednost
objekata koji imaju isti ključ, ideja je da se ti objekti prvo
kombinuju u jedan objekat pa tek onda pošalju u reduce korak.
– ova funkcija se naziva combine i usuštini je ona isto što i
reduce funkcija pa se ponekad može koristiti i prilagođena
reduce funkcija za ove potrebe
Optimizacija Map-Reduce algoritma
Kombinovanje više Map-Reduce algoritama u jedan

• U situacijama kada su map i reduce operacije komplikovane one se


mogu podeliti u više manjih i primeniti Pipe and Filter patern
• Ulaz u map funkciju je rezultat prethodne reduce funkcije
Primer: Potrebno je napraviti poređenje prodaje proizvoda u svakom
mesecu 2011 godine sa prodajom u istom mesecu prethodne godine
• u prvoj fazi primenićemo map reduce algoritam kako bi dobili za svaki
proizvod broj prodaja u jednom mesecu 2011 ili 2010 godine
• u drugoj fazi uzimamo rezultate prve faze i od njih pomoću map-reduce
algoritma dobijamo objekat u kome je za jedan proizvod definisan broj
prodaje za isti mesec u 2010 i 2011 i koliko je to povecanje ili
smanjenje
Rešenje prethodnog primera
Rešenje prethodnog primera
Rešenje prethodnog primera
Kombinovanje više Map-Reduce algoritama u jedan

• Prednosti
– lakše je pisati funkcije koje rade jednostavnije zadatke
– međurezultati ponekad mogu takođe biti od kuristi pa se mogu
sačuvati u posebne agregate (materialized views)
Inkrementalni Map-Reduce algoritam

• Ponekad izvršavanje map i reduce funkcije može dugo da traje čak i na klasteru, a
novi podaci mogu non-stop da pristižu i tada se algoritam mora puštati iz početka,
što i nije efikasno
• Bolje rešenje da se vrši inkrementalno ažuriranje dobijenih rezultata
– map funkcije se mogu puštati inkrementalno jer su nezavisne
– reduce funkcije je malo teže implementirati inkrementalno jer promene u
rezultatima map funkcije utiču na reduce funkciju
• Koliko teško će biti implementirati inkrementalnu reduce funkciju zavisi i da li smo
nekako optimizovali map-reduce algoritam
– ako smo koristili tehniku particionisanja, onda one particije koje se nisu menjale
ne moraju ponovo u reduce korak,
– ako smo koristili combine funkciju nju ne moramo ponavljati ako se nisu
promenili ulazi
Map-Reduce i Mongo
mapReduce komanda

• MongoDB sadrži mapReduce komandu


• Sintaksa:
db.collection.mapReduce(
function() {emit(key,value);}, //map function
function(key,values) {return reduceFunction}, //reduce
{out: collection,
query: document,
sort: document,
limit: number,
finalize:function
}
Sintaksa mapReduce komande

• map - JavaScript funkcija koja selektuje pojedinačan


dokument i primenjuje odgovarajuću funkciju nad njim i
vraća ključ-vrednost objekat
• obavezno mora pozvati funkciju emit() kako bi definisala
ključ-vrednost objekte koji će biti vraćeni
function(){
//radi nesto
emit(key, value)
}
Sintaksa mapReduce komande

• reduce – JavaScript funkcija koja uzima ključ i vrednost i


vraća agregirani rezultat za dati ključ

function(key, value){
//agregira nešto
return result;
}
Sintaksa mapReduce komande

• out – definiše kolekciju u koju će biti snimljen rezultat


• query - definiše kriterijum za izbor dokumenata koji ulaze
u map-reduce algoritam
• sort - definiše uslove sortiranja dokumenata koji ulaze u
map-reduce algoritam
• limit - definiše maksimalan broj dokumenata koji treba da
uđu u map fazu
• finalize – definiše JavaScript funkciju koja će se izvršiti
nad dokumentom nakon reduce koraka
Primer poziva mapReduce komande

kolekcija post sadrži JSON dokumente sledećeg oblika


{
sadrzaj:“Termin za vežbe je pomeren“,
autor: “Milan“,
aktivan: true
}
Primer poziva mapReduce komande

Potrebno je vratiti podatak o tome koliko je svaki korisnik


objavio aktivnih postova
db.posts.mapReduce(
function(){ emit(this.autor,1 )},
function(key, values){return Array.sum(values)},
{
query:{aktivan:true},
out:“post_ukupno“
}
)
Primer 2

• JSON dokument porudžbine

{
"cust_id" : "abc123",
"ord_date" : new Date("Oct 04, 2012"),
"status" : "A",
"items" : [{"sku" : "mmm","qty" : 5,"price" : 3},
{"sku" : "nnn", "qty" : 5, "price" : 2.5}]
}
Primer 2

• Za datu kolekciju porudžbina, vratiti za svaki proizvod


koliko puta je naručen, ukupnu količinu i prosečan broj
naručenih jedinica po porudžbini. U obzir uzeti samo
porudžbine nakon 1.1.2012.
Primer 2
• Map funkcija

var mapFunction = function() {


for (var idx = 0; idx < this.items.length; idx++) {
var key = this.items[idx].sku;
var value = {
count: 1,
qty: this.items[idx].qty
};
emit(key, value);
}
};
Primer 2
• Reduce funkcija

var reduceFunction = function(keySKU, countObjVals) {


var reducedVal = { count: 0, qty: 0 };
for (var idx = 0; idx < countObjVals.length;
idx++) {
reducedVal.count += countObjVals[idx].count;
reducedVal.qty += countObjVals[idx].qty;
}
return reducedVal;
};
Primer 2

• Finalize funkcija

var finalizeFunction = function (key, reducedVal) {


reducedVal.avg = reducedVal.qty/reducedVal.count;
return reducedVal;
};
Primer 2
• mapReduce funkcija

db.posts.mapReduce(
mapFunction,
reduceFunction,
{
out: "map_reduce_example",
query: { ord_date:{ $gt: new Date('01/01/2012')}},
finalize: finalizeFunction
}
)

You might also like