View on GitHub

info

Материјали за курс из УВИТ-а на Математичком факултету Универзитета у Београду

Vežbe

Knjiga


8. MongoDB baza podataka

Cilj ovog poglavlja je upoznavanje studenata sa kreiranjem serverskih aplikacija koji komuniciraju sa MongoDB bazom podataka. Nakon ovog poglavlja, student bi trebalo da razume način funkcionisanja MongoDB baze podataka, kao i da samostalno kreira modele podataka, i da upravlja njima kroz četiri osnovne operacije: pravljenje novih podataka, kao i čitanje, menjanje i brisanje postojećih podataka (engl. Create, Read, Update, Delete, skr. CRUD).

8.1 MongoDB

Baza podataka (engl. database) predstavlja sistem koji se sastoji od struktura podataka i algoritama čija je uloga trajno skladištenje podataka. Pod trajnim skladištenjem smatramo činjenicu da, jednom kada se podaci sačuvaju u bazu podataka, oni ostaju zapamćeni u njoj, čak i kada se aplikacija koja je te podatke upisala u bazu podataka završi. To znači da uvek kada želimo da naše podatke imamo zabeležene nezavisno od životnog veka aplikacije, neophodno nam je da te podatke čuvamo u bazama podataka. Takođe ćemo koristiti i termin sistem za upravljanje bazom podataka, skr. SUBP (engl. database management system, skr. DBMS) koji predstavlja softver koji se koristi za upravljanje bazama podataka. Ti softveri se koriste za kreiranje novih i izmenu postojećih baza podataka, čuvanje podataka i dr.

MongoDB pripada grupi tzv. nerelacionih (engl. NoSQL) SUBP, odnosno, same baze podataka koje se kreiraju su nerelacione. Postoji više vrsta nerelacionih baza podataka, a baze podataka u MongoDB SUBP pripadaju vrsti koja se naziva baza dokumenata (engl. document database). To znači da se svi podaci čuvaju u obliku dokumenata. Format u kojem su zapisani ovi dokumenti je sličan formatu JSON objekata. Vrednosti svojstava (nekada kažemo i polja (engl. field)) dokumenta mogu biti: niske, brojevi, drugi dokumenti, nizovi, nizovi drugih dokumenata, itd. Naredna slika ilustruje primer dokumenta koje je sačuvan u nekoj bazi podataka u MongoDB SUBP.

Bazu podataka u MongoDB SUBP čine kolekcije (engl. collection) dokumenata. Svaki dokument može biti različit, sa proizvoljenim brojem polja, veličine i sadržaja.

Sledeći pojmovi su bitni za razumevanje MongoDB SUBP:

8.2 Instalacija

Kako bi rad sa MongoDB SUBP bio moguć potrebno je preuzeti instalaciju. Odabrati verziju 4.2.2, odgovarajući operativni sistem i paket. Detaljna uputstva za instalaciju možete pogledati ovde.

8.3 MongoDB shell

Korišćenjem MongoDB shell programa možemo se povezati sa bazom i izvršavati različite upite nad kolekcijama koje sadrži. Potrebno je pokrenuti shell skript koji dolazi uz mongo server (<instalacioni_direktorijum>/Server/4.2/bin/mongo).

U nastavku dajemo odabrane naredbe koje je moguće izvršiti u MongoDB shell programu za upravljanje bazama podataka:

MongoDB shell program ne sadrži operaciju za kreiranje nove baze podataka. Umesto toga, baza se automatski kreira kada se u nju trajno zapiše prvi dokument. Tako, na primer, ukoliko MongoDB SUBP nije imao bazu podataka myNewDB, nakon izvršavanja naredne dve naredbe, biće kreirana nova baza podataka myNewDB koja će sadržati jednu kolekciju myNewCollection1 koja će sadržati jedan dokument:

> use myNewDB

> db.myNewCollection1.insertOne( { x: 1 } )

Takođe, vredno je napomenuti da su opisane naredbe primenljive samo u MongoDB shell programu, a ne u drugim radnim okvirima, drajverima i sl. U poglavlju u kojem budemo govorili o Mongoose.js radnom okviru, primetićemo da postoji veliki broj metoda čiji nazivi odgovaraju prethodno opisanim naredbama. Međutim, ne treba ih mešati sa naredbama iznad, već one imaju drugačiju semantiku!

8.4 Upiti

Pre nego što se upustimo u ovu oblast potrebno je da pripremimo podatke za obradu. U datoteci koju možete preuzeti sa ove veze nalaze se podaci o pojedinačnim studentima. Podaci su zadati u JSON formatu i kao takvi se lako mogu uvesti u MongoDB bazu programom mongoimport1:

mongoimport --db <db_name> --collection <collection_name> --file <path>

gde se umesto <db_name> navodi ime baze u koju se uvoze podaci, zatim naziv kolekcije u koju se podaci uvoze umesto <collection_name> i putanju do datoteke koja sadrži podatke umesto <path>.

Zadatak 0. U kolekciju students iz baze Fakultet uvesti podatke o studentima iz datoteke studenti.json.

mongoimport --db Fakultet --collection students --file studenti.json

U nastavku podrazumevamo da smo otvorili MongoDB shell program (mongo) i da smo postavili da radimo sa prethodno uvezenom bazom podataka Fakultet na sledeći način:

> use Fakultet

8.4.1 Upiti čitanja

Da bismo dohvatili podatke iz baze moramo napisati upit (engl. query) koji specifikuje ograničenja koja dokumenti moraju da ispunjavaju da bi bili dohvaćeni. Upiti u MongoDB SUBP predstavljaju objekte čija su svojstva tipovi ograničenja, a vrednosti tih svojstava su vrednosti odgovarajućih ograničenja:

{ 
    <ogranicenje1>: <vrednost1>, 
    <ogranicenje2>: <vrednost2>, 
    ...
}

Specijalno, ako bismo želeli da dohvatimo podatke o svim studentima u kolekciji, koristili bismo prazan upit, odnosno

{}

Zadatak 1. Iz kolekcije students izdvojiti sve studente koji se zovu Jovana.

> db.students.find({name: "Jovana"})

Ukoliko je navedeno više od jednog svojstva, traže se svi dokumenti koji za svako od navedenih naziva polja imaju navedenu vrednost. Ako se bar jedno polje ne poklapa po vrednosti sa zadatom, on neće biti prikazan kao rezultat.

Zadatak 2. Iz kolekcije students izdvojiti sve studente koji se zovu Jovana i čiji je prosek jednak 8.5.

> db.students.find({
    name: "Jovana", 
    avg_grade: "8.5"
})

Na ovaj način dobijamo poređenje vrednosti po jednakosti. Nekada će nam biti potrebno da pronađemo dokumente sa vrednostima koje su manje ili veće od zadate, koje su u nekom intervalu, itd. Definisana su posebna svojstva koja možemo pisati u upitu koja predstavljaju ova ograničenja:

Sintaksa za ove operatore je sledeća:

{ 
    <polje>: {
        $<operator>: <vrednost>
    } 
}

Dakle, za polje čije je ime zadato umesto vrednosti navodimo objekat koji sadrži operator kao svojstvo, a vrednost koja se zadaje predstavlja broj ili niz brojeva sa kojima se poredi vrednost zadatog polja.

Zadatak 3. Iz kolekcije students izdvojiti sve studente sa prosekom većim od 8.5.

> db.students.find({
    avg_grade: {
        $gt : "8.5"
    }
})

Zadatak 4. Iz kolekcije students izdvojiti studente sa prosekom između 8.0 i 9.0.

> db.students.find({
    avg_grade: {
        $gte : "8.0",
        $lte : "9.0"
    }
})

Zadatak 5. Iz kolekcije students izdvojiti studente smerova Informatika i Racunarstvo i informatika.

> db.students.find({
    major: {
        $in : ['Informatika', 'Racunarstvo i informatika']
    }
})

Pored toga, možemo koristiti i svojstva koja imaju ulogu logičkih operatora:

Vrednosti ovih svojstava su nizovi objekata koji predstavljaju logičke jedinice i povezuju se odgovarajućim logičkim operatorom. U slučaju operatora konjunkcije, ukoliko se u nizu nalaze jednostavni objekti, koji su ranije opisani, možemo izostaviti operator i samo razdvajati zarezom sve objekte. Međutim, ukoliko imamo uslove koji su nešto kompleksniji, npr. uslovi koji sadrži i neke druge logičke operatore, onda moramo koristiti $and eksplicitno.

Korišćenje logičkih operatora može se predstaviti sledećim objektom:

{
    $<operator>: [ 
        { <polje1>: <vrednost1> }, 
        { <polje2>: <vrednost2> },
        ... 
    ]
}

Zadatak 6. Iz kolekcije students izdvojiti sve studente čiji je prosek veći od 8.0 sa smera Informatika.

> db.students.find({
    $and: [ 
        { avg_grade: { $gt: 8.0 } }, 
        { major: `Informatika` } 
    ]
})

Prethodni upit predstavlja konjunkciju, i on se može jednostavnije zapisati navođenjem zapete između uslova poređenja, tj.:

> db.students.find({
    avg_grade: { $gt: 8.0 },
    major: `Informatika`
})

Zadatak 7. Iz kolekcije students izdvojiti informacije o studentima čiji je prosek jednak 9.0 ili 10.0 i koji su upisali smer Informatika ili Statistika.

> db.students.find({
    $and: [
        { 
            $or: [ { avg_grade: 9.0 }, { avg_grade: 10.0 } ] 
        },
        {
            $or: [ { major: 'Informatika' }, { major: 'Statistika' } ]
        }
    ]
})

U prethodnim upitima vrednosti polja su poređenje niskama onakve kakve su zadate. Nekada je potrebno proveriti da li vrednost polja počinje ili završava nekom niskom, ili da li sadrži neku nisku.

Zadatak 8. Iz kolekcije students izdvojiti informacije o studentima čije prezime počinje karakterom P.

> db.students.find({ 
    surname: /^P/ 
})

8.4.2 Projekcija u upitima za čitanje vrednosti

Ukoliko ne želimo da u rezultatu dobijemo sva polja za dokumente, možemo iskoristiti projekciju (engl. projection) rezultata. Projekcija predstavlja objekat čija je sintaksa oblika:

{
    <polje1>: <vrednost1>,
    <polje2>: <vrednost2>,
    ...
}

Polja u projekciji predstavljaju polja koja se nalaze u dokumentu, a vrednosti u projekciji mogu biti:

Podrazumevano, ukoliko ne navedemo projekciju, sva polja iz dokumenta će biti dohvaćena. Ukoliko ipak navedemo projekciju, tada će biti dohvaćena samo ona polja koja su eksplicitno navedena da budu uključena (vrednost 1 ili true u projekciji), dok će ostala polja biti isključena iz rezultata. Specijalno, polje _id će se uvek naći u rezultatu, osim ako eksplicitno ne navedemo _id: 0 (ili id_: false) u objektu projekcije.

Zadatak 9: Iz kolekcije students izdvojiti informacije o imenu, prezimenu i prosečnoj oceni onih studenata čije prezime počinje karakterom P.

> db.students.find(
    // Upit
    { 
        surname: /^P/ 
    }
    // Projekcija
    {
        _id: 0,
        name: 1,
        surname: true,
        avg_ocena: 1
    }
)

8.4.3 Upiti za ažuriranje vrednosti polja

Ukoliko bismo želeli da izmenimo neku vrednost upisanu u bazu možemo koristiti neki od sledećih operatora:

Sintaksa ovih svojstava je sledeća:

{ 
    $<svojstvo>: { 
        <polje1>: <vrednost1>, 
        ... 
    } 
}

gde se redom navode imena polja čije se vrednosti menjaju na prethodno opisan način i nove vrednosti za ta polja.

Za više informacija o operatorima ažuriranja možete pogledati ovde.

Zadatak 10. U kolekciji students izmeniti napomenu u Izvanredni studenti informatike svim studentima smera Informatika ili Racunarstvo i informatika čiji je prosek veći od 9.5, a zatim izlistati sav sadržaj kolekcije.

> db.students.updateMany(
    // Prvo navodimo upit koja dokumenta azuriramo
    { 
        $and: [ 
            { $or: [{major: 'Informatika'}, { major: 'Racunarstvo i informatika'}] }, 
            { avg_grade: {$gt: 9.5} }
        ]
    }, 
    // A zatim navodimo upit na koji nacin ta dokumenta azuriramo
    {
        $set: { 
            note: "Izvanredni studenti informatike"
        }
    }
)

> db.students.find()
Domaći zadatak 1
Koristeći komandnu liniju, u MongoDB bazi podataka `Prodavnica`:
  • U kolekciju `artikli` uvesti podatke o artiklima iz datoteke artikli.json.
  • U kolekciju `produzbine` uvesti podatke o porudžbinama iz datoteke porudzbine.json.
Domaći zadatak 2
U alatu komandne linije `mongo` u MongoDB bazi podataka `Prodavnica` izdvojiti nazive artikala čiji je broj artikala veći od 0.
Domaći zadatak 3
U alatu komandne linije `mongo` u MongoDB bazi podataka `Prodavnica` izdvojiti sve informacije o artiklu sa identifikatorom `5e0e28d07bf8582054b53cac`.
Domaći zadatak 4
U alatu komandne linije `mongo` u MongoDB bazi podataka `Prodavnica` smanjiti broj artikala za 7 onim artiklima čiji nazivi počinju slovom `P` i koji imaju više od 6 artikla.
Domaći zadatak 5
U alatu komandne linije `mongo` u MongoDB bazi podataka `Prodavnica` obrisati sve artikle čiji je broj artikala jednak 0.
Domaći zadatak 6
U alatu komandne linije `mongo` u MongoDB bazi podataka `Prodavnica` dodati informaciju o narednoj porudžbini: Bojan Petrović je 22. decembra 2019. godine poručio 5 artikla sa identifikatorom `5e0e289200bc1b20545a43a3`, a isporuka je izvršena 25. decembra 2019. godine.
Domaći zadatak 7
U alatu komandne linije `mongo` u MongoDB bazi podataka `Prodavnica` izdvojiti sve porudžbine proizvoda čiji je identifikator `5e0e289200bc1b20545a43a3`.
Domaći zadatak 8
U alatu komandne linije `mongo` u MongoDB bazi podataka `Prodavnica` izdvojiti porudžbine svih ljudi koji se prezivaju `Peric`.

Knjiga

Vežbe

  1. Program mongoimport nalazi se u istom direktorijumu gde i mongo