IEP/K1 Septembar 2021
Prvi kolokvijum u septembarskom roku 2021. godine održan je 17. septembra.
Postavka
Kompanija ugovara projekte izrade softvera po narudžbini klijenta. U kompaniji su zaposleni programeri i menadžeri. U sistemu se vodi evidencija o svakom koraku rada (zahtevima, dodeljenim poslovima, razvijenom kodu). Za svaki projekat nekog klijenta, evidentiraju se datum kreiranja, menadžer koji je nadležan za njega kao i svi korisnički zahtevi. Pre nego što projekat otpočne, on mora biti isplaniran (a nakon planiranja status projekta postaje I). Planiranje projekta se sastoji u tome da se za svaki korisnički zahtev definiše posao, kao i koliko će izrada tog posla trajati i koliko će programera biti angažovano na tom poslu. Nakon toga se određuju programeri i dodeljuje im se angažman na pojedinim poslovima. Implementacija projekata može da otpočne tek nakon što se projekat isplanira. Tokom implementacije, celokupan kod koji programeri razvijaju se takođe evidentira u sistemu i to tako da je za svaki deo koda definisano koje korisničke zahteve implementira.
KLIJENT (SifK, Naziv, Kontakt) RADNIK (SifR, Ime) MENADZER (SifR, Iskustvo) PROGRAMER (SifR, Specijalnost) PROJEKAT (SifP, Naziv, Status, Vrednost, Datum, SifK, SifR) ZAHTEV (SifZ, Opis, SifP) POSAO (SifJ, Trajanje, BrProgramera, SifP, SifZ) ANGAZMAN (SifA, SifR, SifJ) KOD (SifK, Kod) IMPLEMENTIRA (SifK, SifZ)
- Navesti po jedan primer svakog entiteta [...]
- Sastaviti skript koji koristeći funkciju za agregaciju (aggregation framework) vraća šifre i nazive onih projekata koje imaju vrednost preko 1000, a pri tome imaju i više od 8 poslova sa trajanjem preko 200.
- Sastaviti Map/Reduce posao koji za svaki datum kada je kreiran bar jedan projekat vraća informaciju o prosečnom broju korisničkih zahteva.
1. zadatak
Radnik
{
"_id": 1,
"Ime": "Pera",
// Menadzer
"Iskustvo": null,
// Programer
"Specijalnost": "Docker"
}
Projekat
{
"_id": 1,
"Naziv": "Softverska kompanija",
"Status": "I",
"Vrednost": 10000,
"Datum": "2022-03-03T20:00:00Z",
// Klijent
"Klijent": {
"Naziv": "Microsoft",
"Kontakt": "[email protected]"
},
"Menadzer": 4,
// Posao
"Poslovi": [
{
"Zahtev": 1,
"Trajanje": 90,
// Angazman
"Programeri": [1, 2, 3, 4, 5]
}
],
"Zahtevi": [1, 2, 3, 4]
}
Zahtev
{
"_id": 1,
"Opis": "Tabela Implementira"
}
Kod
{
"Kod": "int main() {...}",
// Implementira
"Zahtevi": [1, 2, 3, 4]
}
2. zadatak
db.Projekat.aggregate([
// Филтрирање пројеката са вредношћу мањом од 1000.
{
$match: {
Vrednost: {
$gt: 1000
}
}
},
// Дељење сваког пројекта тако да се сваки посао налази у одвојеном објекту.
{
$unwind: "$Poslovi"
},
// Избацивање послова са мање од 200 трајања.
{
$match: {
"Poslovi.Trajanje": {
$gt: 200
}
}
},
// Груписање пројеката назад са бројањем послова.
{
$group: {
_id: "$_id",
BrojPoslova: {
$count: {}
},
Naziv: {
$first: "$Naziv"
}
}
},
// Филтрирање пројеката са мање од 8 послова који имају преко 200 трајања.
{
$match: {
BrojPoslova: {
$gt: 8
}
}
},
// Враћање у траженом облику.
{
$project: {
sifra: "$_id",
naziv: "$Naziv"
}
}
]);
3. zadatak
function map() {
emit(this.Datum, {
sum: this.Zahtevi.length,
count: 1,
avg: 0
});
}
function reduce(key, values) {
return {
sum: Array.sum(values.map(v => v.sum)),
count: Array.sum(values.map(v => v.count)),
avg: 0
};
}
function finalize(key, value) {
value.avg = value.sum / value.count;
return value;
}
db.Projekat.mapReduce(map, reduce, {out: 'k1_septembar_2021_c', finalize});
Testiranje
Rešenja iznad možete testirati nad sledećom bazom:
db.createCollection('Radnik');
db.createCollection('Projekat');
db.createCollection('Zahtev');
db.createCollection('Kod');
db.Projekat.insertMany([
{
_id: 1,
Naziv: 'Softverska kompanija',
Status: 'I',
Vrednost: 10000,
Datum: '2022-03-03T20:00:00Z',
Klijent: {
Naziv: 'Microsoft',
Kontakt: '[email protected]'
},
Menadzer: 4,
Poslovi: [
{
Zahtev: 1,
Trajanje: 201,
Programeri: [1, 2, 3, 4, 5]
},
{
Zahtev: 2,
Trajanje: 201,
Programeri: [1, 2, 3, 4, 5]
},
{
Zahtev: 3,
Trajanje: 201,
Programeri: [1, 2, 3, 4, 5]
},
{
Zahtev: 4,
Trajanje: 201,
Programeri: [1, 2, 3, 4, 5]
},
{
Zahtev: 5,
Trajanje: 201,
Programeri: [1, 2, 3, 4, 5]
},
{
Zahtev: 6,
Trajanje: 201,
Programeri: [1, 2, 3, 4, 5]
},
{
Zahtev: 7,
Trajanje: 201,
Programeri: [1, 2, 3, 4, 5]
},
{
Zahtev: 8,
Trajanje: 201,
Programeri: [1, 2, 3, 4, 5]
},
{
Zahtev: 9,
Trajanje: 201,
Programeri: [1, 2, 3, 4, 5]
}
],
Zahtevi: [1, 2, 3, 4, 5, 6, 7, 8, 9]
},
// ...
]);
db.Radnik.insertMany([
{_id: 1, Ime: 'Pera', Iskustvo: null, Specijalnost: 'Docker'},
{_id: 2, Ime: 'Mika', Iskustvo: 2, Specijalnost: null},
{_id: 3, Ime: 'Žika', Iskustvo: null, Specijalnost: 'C#'},
{_id: 4, Ime: 'Miloš', Iskustvo: 10, Specijalnost: null},
{_id: 5, Ime: 'Zaharije', Iskustvo: null, Specijalnost: 'Docker'},
{_id: 6, Ime: 'Jovan', Iskustvo: null, Specijalnost: 'Python'}
]);
db.Zahtev.insertMany([
{_id: 1, Opis: 'Tabela Klijent'},
{_id: 2, Opis: 'Tabela Radnik'},
{_id: 3, Opis: 'Tabela Menadzer'},
{_id: 4, Opis: 'Tabela Programer'},
{_id: 5, Opis: 'Tabela Projekat'},
{_id: 6, Opis: 'Tabela Zahtev'},
{_id: 7, Opis: 'Tabela Posao'},
{_id: 8, Opis: 'Tabela Angazman'},
{_id: 9, Opis: 'Tabela Kod'},
{_id: 10, Opis: 'Tabela Implementira'}
]);
db.Kod.insertMany([
{_id: 1, Kod: 'int main(void) {return 0;}', Zahtevi: [1, 2, 3, 4]},
{_id: 2, Kod: 'def main():\n print("Hello world")', Zahtevi: [5, 6, 7, 8]},
{_id: 3, Kod: 'System.out.println("Hello world");', Zahtevi: [9, 10]}
]);