LEKCJA 07 - EXPRESS (p) - MongoDB - CRUD

LEKCJA 07 - EXPRESS (p) - MongoDB - CRUD
ukryj menu
SPEC
aktualizacja: 2021-12-06 08:03:59


1. Opis zajęć

Celem zajęć jest zapoznanie się z pracą na serwerze bazodanowym MongoDB
Jest to serwer bazy danych, tzn w odróżnieniu od poznanej wcześniej bazy danych NeDB, jest uruchamiany na określonym adresie
w sieci, umożliwiając dostęp z dowolnej aplikacji webowej czy mobilnej.
Zaletą systemu jest podobieństwo poleceń do NeDB (która korzysta z podobnego do MongoDB schematu poleceń)
MongoDB jest bazą NoSQL, a więc zapisuje dane w postaci obiektów, a nie tabeli i rekordów
Zapisane dane są zaszyfrowane,a nie jawnie widoczne w postaci tekstu, jak to było w przypadku NeDB


Udział MongoDB w rynku:

https://idatalabs.com/tech/products/mongodb

2. instalacja serwera MongoDB

Uwaga: na pracowni już wszystko zainstalowane, w wersji serwera 5.0
W odróżnieniu od prostego pakietu NeDB, zaawansowany system MongoDB pełni rolę serwera baz danych, pobieramy go z lokalizacji

https://www.mongodb.com/try/download/community

instalujemy najlepiej w lokalizacji (Windows)
wybieramy Custom, co pozwala na  pominięcie dodatków do serwera (Atlas, Compass)


c:\MongoDBkopiuj

jeśli się nie tworzy automatycznie, w tym samym miejscu tworzymy katalog na pliki baz danych:

c:\data\dbkopiuj

zainstalowaną wersję można sprawdzić w konsoli ustawionej na katalog \bin serwera MongoDB

mongod --versionkopiuj

3. start serwera MongoDB (Windows)

serwer MongoDB startuje automatycznie przy starcie Windows jako usługa, i nie trzeba go startować ręcznie
jednak dla testów można to zmienić (czyli aby nie startował automatycznie, tylko musiał być uruchomiony ręcznie):


konto admina / regedit

HKEY_LOCAL_MACHINE / System / CurrentControlSet / Services

MongoDB

prawy klawisz / usuń

uruchomienie serwera MongoDB z katalogu /bin (musi mieć minimalnie 4GB wolnego miejsca na dysku)

mongodkopiuj

jeśli nie ma 4GB miejsca to uruchamiamy z parametrem

mongod --smallfiles

4. klient mongo

dla opanowania poleceń na bazie danych i kontroli czy wszystko działa poprawnie,
wykorzystamy klienta mongo, uruchamiając z konsoli /bin:

mongokopiuj

5. podstawowe komendy klienta mongo

proszę o przećwiczenie poniższych poleceń w konsoli klienta mongo
z uruchomionym serwerem bazodanowym MongoDB
na razie bez uruchamiania serwera webowego Express


help - wybrane polecenia klienta mongo
show dbs - nazwy wszystkich baz danych
db - nazwa bieżącej bazy
use nazwa_bazy - ustalenie bieżącej bazy
show collections - nazwy kolekcji w bieżącej bazie
db.createCollection("nazwa_kolekcji") - utworzenie kolekcji
db.nazwa_kolekcji.find() - wyświetlenie zawartości wybranej kolekcji
db.nazwa_kolekcji.find().pretty() - z formatowaniem
db.nazwa_kolekcji.drop() - usunięcie kolekcji
db.nazwa_kolekcji.insert({"login":"aaa"}) - wstawienie dokumentu do kolekcji
db.nazwa_kolekcji.deleteOne({"login":"aaa"}) - usuwanie dokumentu z kolekcjikopiuj


więcej poleceń

https://docs.mongodb.com/manual/reference/mongo-shell/kopiuj

6. ćwiczenie CRUD (Create, Read, Update, Delete)

- zapis w bazie MongoDB obiektu usera (login, password)
- pobranie z bazy i wypisanie na stronie wszystkich userów
- usunięcie z bazy usera wg id wybranego z selecta
- aktualizacja w bazie hasła usera wg id wybranego z selecta


operacje CRUD - create, read, update, delete:

https://pl.wikipedia.org/wiki/CRUDkopiuj

7. Struktura projektu: serwer Express

{appDir}    
|
|__ modules
|     |__ Operations.js // plik z funkcjami bazodanowymi, na serwerze
|
|__ static
|     |__ index.html
|  
|__ server.jskopiuj




8. podłączenie do bazy z poziomu Expressa - potrzebne zmienne

sterownik do obsługi bazy Mongo z poziomu Expressa

npm install mongodb@2.2kopiuj

utworzenie klienta mongodb

const mongoClient = require('mongodb').MongoClientkopiuj

utworzenie obiektu ObjectID, potrzebnego potem do operacji na _id danego dokumentu (podczas usuwania i aktualizacji)

const ObjectID = require('mongodb').ObjectID;kopiuj

obiekt bazy danych mongoDB

let _db;kopiuj


9. obsługa połączenia z MongoDB na serwerze Express oraz utworzenie bazy danych o nazwie nazwa_bazy


POZA server.listen(3000) :

mongoClient.connect("mongodb://localhost/nazwa_bazy", function (err, db) {
    if (err) console.log(err)
    else console.log("mongo podłączone!")
    //tu można operować na utworzonej bazie danych db lub podstawić jej obiekt
    // pod zmienną widoczną na zewnątrz    
    _db = db;
})kopiuj


uwaga 1: powyższe połączenie działa dla różnych wersji mongodb (przetestowane na 3.2, 3.4, 3.6, 4.0, 5.0)
sterownik ma być koniecznie instalowany poleceniem npm install mongodb@2.2
uwaga 2: utworzona baza jest widoczna w konsoli klienta mongo DOPIERO po dodaniu przynajmniej jednej kolekcji / dokumentu

10. utworzenie kolekcji w bazie danych

wewnątrz funkcji mongoClient.connect utwórz kolekcję

db.createCollection("nazwakolekcji", function (err, coll) {
   console.log("kolekcja powstała, sprawdź efekt w konsoli klienta mongo")
})kopiuj


na tej kolekcji będą wykonywane operacje CRUD - czyli dodaj, pobierz, aktualizuj, usuń dokument
przetestuj w konsoli mongo czy widać bazę danych nazwa_bazy


11. utworzenie dokumentu w kolekcji

wewnątrz funkcji db.createCollection utwórz dokument czyli obiekt z danymi, np {a:1}

coll.insert({a:1}, function (err, result) {                
   console.log("dokument powstał, sprawdź efekt w konsoli klienta mongo")
});kopiuj


przetestuj w konsoli mongo czy widać kolekcję nazwakolekcji
oraz dokument / obiekt w niej


12. plik Operations.js - export obiektu zawierającego podstawowe operacje na bazie MongoDB

utworzenie modułu dla operacji CRUD (Create, Read, Update, Delete),
czyli załadowanie pliku Operations.js z katalogu modules równoległego do server.js  


const opers = require("./modules/Operations.js")
console.log(opers)kopiuj


poniżej mieści się cała zawartość pliku Operations.js,
który zawiera zestaw funkcji do operowania na bazie MongoDB
(nazwy funkcji, np SelectAll tworzymy sami, nie są narzucone)

module.exports = {    
      
        //insert

        InsertToDatabase: function (collection, data) {
            collection.insert(data, function (err, result) {                
                console.log(result)
            });
        },

        //select all - zwraca tablicę pasujących dokumentów

        SelectAllFromDatabase: function (collection) {
            collection.find({}).toArray(function (err, items) {
                console.log(items)
            });
        },

        //select - zwraca tablicę pasujących dokumentów, z ograniczeniem do {login:"test"}

        SelectAndLimit: function (collection) {
            collection.find({login: "test"}).toArray(function (err, items) {
                console.log(items)
            });
        },

        //delete - usunięcie poprzez id - uwaga na ObjectID

        DeleteById: function (ObjectID, collection, id) {
            collection.remove({ _id: ObjectID(id) }, function (err, data) {
                console.log(data)
            })
        },

        // update - aktualizacja poprzez id - uwaga na ObjectID - to funkcja, a nie string
        // uwaga: bez $set usuwa poprzedni obiekt i wstawia nowy
        // z $set - dokonuje aktualizacji tylko wybranego pola

        UpdateById: function (ObjectID, collection, data){
            collection.updateOne(
                { _id: ObjectID("id_dokumentu_ktory_chcemy_usunac") },
                { $set: { pass: "test" } },
                function (err, data) {
                    console.log("update: "+data)                  
                })
        },
     
}kopiuj




13. Użycie ww funkcji - operacje na bazie danych

kolekcję na której będziemy pracować można utworzyć wewnątrz mongoClient.connect
potem, np w funkcjach obsługujących post-a możemy wykonywać operacje na bazie MongoDB,
korzystając z przygotowanego modułu Operations.js

przykłady użycia

INSERT

const data =
{
   a: "1",
   b: "2",
};

const coll = db.collection("usersi")
opers.InsertToDatabase(coll, data)kopiuj


SELECT

poniższa operacja wypisze w konsoli Expressa dodane dane

opers.SelectAllFromDatabase(coll)kopiuj

UPDATE

poniższa operacja zaktualizuje dokument w kolekcji, wg przesłanego ObjectID i danych

opers.UpdateById(ObjectID, coll, data)kopiuj

DELETE

poniższa operacja usunie z kolekcji dokument z danym _id

opers.DeleteById(ObjectID, coll, "id_ktore_chcemy_usunac")
kopiuj


14. Jak zwrócić dane z powyższych funkcji MongoDB ?

a) można użyć callbacka

wobec faktu że mongo, node działają asynchronicznie, dane z bazy można uzyskać stosując callback,
czyli funkcję przekazaną w argumencie innej funkcji


https://en.wikipedia.org/wiki/Callback_(computer_programming)

przykład SELECTA, z ograniczeniem ilości wyszukanych wyników (jedna z funkcji w pliku Operations.js)



SelectAndLimit: function (collection, callback) {
   collection.find({login: "test"}).toArray(function (err, items) {
      console.log(items)
      if (err) console.log(err)
      //funkcja zwracająca dane na zewnątrz
      else callback(items)
   });
},kopiuj


teraz użycie powyższej funkcji w kodzie serwera (dane są dostępne dopiero wewnątrz funkcji anonimowej czyli tam gdzie console.log):

opers.SelectAndLimit (coll,function (data) {            
     console.log(data)
})
kopiuj


b) do komunikacji klient-serwer używamy fetch-a