Mongoose este un cadru JavaScript care este utilizat în mod obișnuit într-o aplicație Node.js cu o bază de date MongoDB. În acest articol, vă prezint Mongoose și MongoDB și, mai important, unde aceste tehnologii se potrivesc cu aplicația dvs..
Să începem cu MongoDB. MongoDB este o bază de date care stochează datele dvs. ca documente. Cel mai frecvent aceste documente se aseamănă cu o structură asemănătoare JSON:
firstName: "Jamie", ultimName: "Munro"
Un document este apoi plasat într-o colecție. De exemplu, exemplul documentului de mai sus definește a utilizator
obiect. Acest utilizator
obiect ar fi de obicei parte dintr-o colecție numită utilizatori
.
Unul dintre factorii cheie cu MongoDB este flexibilitatea în ceea ce privește structura. Chiar dacă în primul exemplu, utilizator
obiect conținea a Nume
și numele de familie
proprietăți, aceste proprietăți nu sunt necesare în fiecare utilizator
document care face parte din utilizatori
Colectie. Acest lucru face ca MongoDB să fie foarte diferită de o bază de date SQL ca MySQL sau Microsoft SQL Server care necesită o schemă de bază de date definită puternic pentru fiecare obiect pe care îl stochează.
Abilitatea de a crea obiecte dinamice care sunt stocate ca documente în baza de date este locul unde Mongoose intră în joc.
Mongoose este un Document Mapper Object (ODM). Acest lucru înseamnă că Mongoose vă permite să definiți obiecte cu o schemă puternic tastat care este mapat la un document MongoDB.
Mongoose oferă o cantitate incredibilă de funcționalități în ceea ce privește crearea și lucrul cu schemele. Mongoose conține în prezent opt SchemaTypes pe care o proprietate este salvată ca atunci când este persistentă la MongoDB. Sunt:
Fiecare tip de date vă permite să specificați:
Pe lângă aceste opțiuni comune, anumite tipuri de date vă permit să personalizați în continuare modul în care datele sunt stocate și preluate din baza de date. De exemplu, a Şir
tipul de date vă permite de asemenea să specificați următoarele opțiuni suplimentare:
Număr
și Data
proprietățile suportă specificarea unei valori minime și maxime care este permisă pentru acel câmp.
Cele mai multe dintre cele opt tipuri de date permise ar trebui să vă fie destul de familiare. Cu toate acestea, există câteva excepții care ar putea să vă sară, cum ar fi Tampon
, Amestecat
, objectId
, și mulțime
.
Tampon
tipul de date vă permite să salvați date binare. Un exemplu comun de date binare ar fi o imagine sau un fișier codificat, cum ar fi un document PDF.
Amestecat
tipul de date transformă proprietatea într-un câmp "orice merge". Acest câmp seamănă cu numărul de dezvoltatori care utilizează MongoDB deoarece nu există o structură definită. Aveți grijă să utilizați acest tip de date deoarece pierde multe dintre caracteristicile minunate pe care le oferă Mongoose, cum ar fi validarea datelor și detectarea modificărilor entității pentru a ști automat să actualizeze proprietatea atunci când salvează.
objectId
tipul de date specifică în mod obișnuit un link spre alt document din baza dvs. de date. De exemplu, dacă ați avea o colecție de cărți și de autori, documentul de carte ar putea conține un objectId
proprietate care se referă la autorul specific al documentului.
mulțime
tipul de date vă permite să stocați matrice de tip JavaScript. Cu un tip de date Array, puteți efectua operațiuni obișnuite de array JavaScript pe ele, cum ar fi împingere, pop, schimbare, felie etc..
Înainte de a trece și de a genera un cod, am vrut doar să recapitulăm ceea ce tocmai am învățat. MongoDB este o bază de date care vă permite să stocați documente cu o structură dinamică. Aceste documente sunt salvate într-o colecție.
Mongoose este o bibliotecă JavaScript care vă permite să definiți schemele cu date puternic introduse. Odată ce o schemă este definită, Mongoose vă permite să creați un model bazat pe o schemă specifică. Un model Mongoose este apoi cartografiat unui document MongoDB prin definiția schemei modelului.
După ce ați definit schemele și modelele, Mongoose conține multe funcții diferite care vă permit să validați, să salvați, să ștergeți și să interogați datele utilizând funcțiile comune MongoDB. Voi vorbi mai mult despre exemplele concrete de cod care urmează.
Înainte de a începe să creăm schemele și modelele Mongoose, MongoDB trebuie să fie instalat și configurat. Aș sugera să vizitați pagina de descărcare a MongoDB. Există mai multe opțiuni diferite de instalat. Am conectat la serverul comunitar. Aceasta vă permite să instalați o versiune specifică sistemului dvs. de operare. MongoDB oferă, de asemenea, un server Enterprise și o instalare de asistență în cloud. Deoarece cărțile întregi ar putea fi scrise despre instalarea, reglarea și monitorizarea MongoDB, am de gând să rămân cu Serverul comunitar.
Odată ce ați descărcat și instalat MongoDB pentru sistemul dvs. de operare ales, va trebui să porniți baza de date. În loc să reinventam roata, aș sugera să vizitez documentația lui MongoDB cu privire la modul de instalare a MongoDB Community Edition.
Voi astepta aici in timp ce configurati MongoDB. Când sunteți gata, putem trece la configurarea Mongoose pentru a vă conecta la baza de date MongoDB nou instalată.
Mongoose este un cadru JavaScript, și o să-l folosesc într-o aplicație Node.js. Dacă aveți deja instalat Node.js, puteți trece la următorul pas. Dacă nu aveți instalat Node.js, vă sugerăm să începeți vizitând pagina Descărcare Node.js și selectând programul de instalare pentru sistemul de operare.
Cu Node.js setat și gata de plecare, am de gând să creez o nouă aplicație și apoi să instalez pachetul Mongoose NPM.
Cu un prompt de comandă setat la locul în care doriți să fie instalată aplicația dvs., puteți rula următoarele comenzi:
mkdir mongoose_basics cd mongoose_basics npm init
Pentru inițializarea aplicației mele, am lăsat totul ca valori implicite. Acum o să instalez pachetul de mongoasă după cum urmează:
npm instala mongoose - salveaza
Cu toate precondițiile configurate, hai să ne conectăm la o bază de date MongoDB. Am plasat următorul cod într-un fișier index.js deoarece am ales ca punct de plecare pentru cererea mea:
var mongoose = necesită ("mongoose"); mongoose.connect ( 'MongoDB: // localhost / mongoose_basics');
Prima linie de cod include mangustă
bibliotecă. Apoi, deschid o conexiune la o bază de date pe care am sunat-o mongoose_basics
folosind conectați
funcţie.
conectați
Funcția acceptă alți doi parametri opționali. Al doilea parametru este un obiect de opțiuni în care puteți defini lucruri precum numele de utilizator și parola, dacă este necesar. Al treilea parametru, care poate fi și al doilea parametru dacă nu aveți opțiuni, este funcția de apel invers după ce ați încercat să vă conectați. Funcția de apel invers poate fi utilizată în unul din două moduri:
mongoose.connect (uri, opțiuni, funcție (eroare) // Verificați eroarea în conexiunea inițială. Nu există paramă 2 la apelul invers.); // sau folosind promisiunile mongoose.connect (uri, opțiuni) .then (() => / ** gata de utilizare. Promisiunea "mongoose.connect ()" rezolvă nedefinit. * /, Err = ** gestionați eroarea inițială de conectare * /);
Pentru a evita o introducere potențială a promisiunilor JavaScript, voi folosi prima metodă. Mai jos este un fișier index.js actualizat:
var mongoose = necesită ("mongoose"); mongoose.connect ('mongodb: // localhost / mongoose_basics', funcția (err) if (err) throw err; console.log ('Conectat cu succes');));
Dacă apare o eroare la conectarea la baza de date, excepția este aruncată și orice procesare ulterioară este oprită. Când nu apare nici o eroare, am înregistrat un mesaj de succes în consola.
Mongoose este acum configurat și conectat la o bază de date numită mongoose_basics
. Conexiunea mea MongoDB nu utilizează nici un nume de utilizator, o parolă sau un port personalizat. Dacă trebuie să setați aceste opțiuni sau orice altă opțiune în timpul conexiunii, vă sugerăm să consultați documentația Mongoose privind conectarea. Documentația oferă explicații detaliate cu privire la numeroasele opțiuni disponibile, precum și cum se creează mai multe conexiuni, punerea în comun a conexiunilor, replici etc.
Cu o conexiune reușită, hai să mergem mai departe pentru a defini o schemă Mongoose.
În timpul introducerii, am arătat a utilizator
obiect care conține două proprietăți: Nume
și numele de familie
. În următorul exemplu, am tradus acest document într-o schemă Mongoose:
var userSchema = mongoose.Schema (firstName: String, lastName: String);
Aceasta este o schemă de bază care conține doar două proprietăți fără atribute asociate cu aceasta. Să ne extindem la acest exemplu prin transformarea proprietăților primului și ultimului nume în obiecte copil a Nume
proprietate. Nume
proprietatea va cuprinde atât numele, cât și numele de familie. De asemenea, voi adăuga a creată
proprietate care este de tip Data
.
var userSchema = mongoose.Schema (nume: primaName: String, lastName: String, creat: Date);
După cum puteți vedea, Mongoose îmi permite să creez scheme foarte flexibile cu multe combinații posibile între modul în care pot organiza datele mele.
În următorul exemplu, voi crea două noi scheme care vor demonstra cum să creați o relație cu o altă schemă: autor
și carte
. carte
schema va conține o trimitere la autor
schemă.
var autorSchema = mongoose.Schema (_id: mongoose.Schema.Types.ObjectId, nume: firstName: String, lastName: String, biografie: String, twitter: String, creat: type: Date, default: Date.now);
Mai sus este autor
schema care extinde conceptele utilizator
schema pe care am creat-o în exemplul anterior. Pentru a face legătura între autor și carte, prima proprietate a autor
schema este un _id
proprietate care este un objectId
tipul de schemă. _id
este sintaxa comună pentru crearea unei chei primare în Mongoose și MongoDB. Apoi, cum ar fi utilizator
schema, am definit a Nume
proprietate care conține numele și prenumele autorului.
Extinderea pe utilizator
schema, autor
conține mai multe altele Şir
tipuri de scheme. Am adăugat și o Tampon
tipul de schemă care ar putea conține imaginea de profil a autorului. Proprietatea finală deține data creată a autorului; cu toate acestea, este posibil să observați că este creat ușor diferit deoarece a definit o valoare implicită "acum". Când un autor este persistent în baza de date, această proprietate va fi setată la data / ora curente.
Pentru a finaliza exemplele de schemă, să creați o carte
schema care conține o referință la autor folosind objectId
tipul schemei:
var bookSchema = mongoose.Schema (_id: mongoose.Schema.Types.ObjectId, title: String, rezumat: String, isbn: String, thumbnail: Buffer, autor: type: mongoose.Schema.Types.ObjectId, Author ', evaluări: [rezumat: String, detaliu: String, numberOfStars: Număr, creat: type: Date, default: Date.now], creat: type: Date, default: Date.now );
carte
schema conține mai multe proprietăți de tip Şir
. După cum sa menționat mai sus, aceasta conține o referință la autor
schemă. Pentru a demonstra în continuare definițiile puternice ale schemelor, carte
schema conține, de asemenea, un mulțime
de evaluări
. Fiecare rating este format din: a rezumat
, detaliu
, numberOfStars
, și creată
data de proprietate.
Mongoose vă oferă flexibilitatea de a crea scheme cu referințe la alte scheme sau, ca în exemplul de mai sus cu evaluări
proprietate, vă permite să creați un mulțime
din proprietățile copilului care ar putea fi cuprinse într-o schemă asociată (cum ar fi o carte către autor) sau în linie ca în exemplul de mai sus (cu carte la o evaluare mulțime
).
Din moment ce autor
și carte
schemele demonstrează flexibilitatea schemelor Mongoose, voi continua să folosesc aceste scheme și să obțin un Autor
și Carte
model de la ei.
var Autor = mongoose.model ("Autor", autorSchema); var carte = mongoose.model ("carte", bookSchema);
Un model de Mongoose, atunci când este salvat, creează un document în MongoDB cu proprietățile definite de schema derivată din.
Pentru a demonstra crearea și salvarea unui obiect, în următorul exemplu, voi crea mai multe obiecte: an Autor
Model și mai multe Carte
Modele. Odată creat, aceste obiecte vor fi persistente în MongoDB folosind Salvați
metoda modelului.
var jamieAuthor = autor nou jid: new mongoose.Types.ObjectId (), nume: nume_familie: 'Jamie', lastName: 'Munro', biografie: 'Jamie este autorul ASP.NET MVC 5 cu Bootstrap și Knockout .js. ", Twitter:" https://twitter.com/endyourif ", facebook:" https://www.facebook.com/End-Your-If-194251957252562/ '; jamieAuthor.save (funcția (err) if (err) throw err; console.log ('Autor salvat cu succes'); var mvcBook = carte nouă _id: new mongoose.Types.ObjectId (), title: 'ASP. NET MVC 5 cu Bootstrap și Knockout.js ', autor: jamieAuthor._id, evaluări: [summary:' Great read ']; mvcBook.save (funcția (err) if (err) throw err; ("Rezervați cu succes salvată");); var knockoutBook = carte nouă _id: new mongoose.Types.ObjectId (), title: 'Knockout.js: Crearea aplicațiilor web dinamice client-side', autor: jamieAuthor._id ; knockoutBook.save (funcția (err) if (err) throw err; console.log ("Salvați salvarea cu succes");););
În exemplul de mai sus, am conectat fără rușine o referință la cele două cărți cele mai recente. Exemplul începe prin crearea și salvarea unui jamieObject
care este creat dintr-unAutor
Model. În interiorul Salvați
funcția jamieObject
, dacă apare o eroare, aplicația va afișa o excepție. Când salvarea este reușită, în interiorul Salvați
, cele două obiecte de carte sunt create și salvate. Similar cu jamieObject
, dacă apare o eroare la salvare, se emite o eroare; în caz contrar, în consola se emite un mesaj de succes.
Pentru a crea referința la autor, obiectele cărții fac trimitere la autor
lui schemă _id
cheia primară în autor
proprietate a carte
schemă.
Este destul de comună pentru datele care vor ajunge la crearea unui model care să fie populat de un formular pe o pagină Web. Din această cauză este o idee bună să validați aceste date înainte de a salva modelul în MongoDB.
În următorul exemplu, am actualizat schema autorului anterior pentru a adăuga validarea următoarelor proprietăți: Nume
, stare de nervozitate
, Facebook
, și linkedin
.
var autorSchema = mongoose.Schema (_id: mongoose.Schema.Types.ObjectId, nume: firstName: type: String, required: true, lastName: String, biografie: String, twitter: type: String, validate : validator: funcție (text) retur text.indexOf ('https://twitter.com/') === 0;, mesaj: 'mânerul Twitter trebuie să înceapă cu https://twitter.com/' , facebook: type: String, validate: validator: function (text) retur text.indexOf ('https://www.facebook.com/') === 0; cu https://www.facebook.com/ ', linkedin: type: String, validate: validator: function (text) retur text.indexOf (' https://www.linkedin.com/) === 0;, mesaj: 'LinkedIn trebuie să înceapă cu https://www.linkedin.com/', profilePicture: Buffer, creat: type: Date, default: Date.now);
Nume
proprietate a fost atribuită necesar
proprietate. Acum când îl sun Salvați
funcția Mongoose va afișa o eroare cu un mesaj care indică Nume
proprietatea este obligatorie. Am ales să nu fac asta numele de familie
proprietatea necesară în cazul în care Cher sau Madonna urmau să fie autori în baza mea de date.
stare de nervozitate
, Facebook
, și linkedin
toate proprietățile au validatori personalizați foarte asemănători aplicați acestora. Fiecare dintre ei se asigură că valorile încep cu numele de domeniu respectiv al rețelelor sociale. Aceste câmpuri nu sunt necesare, astfel încât validatorul va fi aplicat numai atunci când sunt furnizate date pentru acea proprietate.
O introducere la Mongoose nu ar fi completă fără un exemplu de căutare a unei înregistrări și actualizare a uneia sau a mai multor proprietăți pe acel obiect.
Mongoose oferă mai multe funcții diferite pentru a găsi date pentru un anumit model. Funcțiile sunt găsi
, găsește una
, și findById
.
găsi
și găsește una
funcțiile acceptă un obiect ca intrare care să permită căutări complexe, în timp ce findById
acceptă doar o singură valoare cu o funcție de apel invers (un exemplu va urma în scurt timp). În următorul exemplu, voi demonstra cum să găsiți toate titlurile care conțin șirul "mvc".
Book.find (title: / mvc / i) exec (funcție (err, cărți) if (err) throw err; console.log (books);
În interiorul găsi
, eu sunt în căutarea pentru șir insensibil de caz "mvc" pe titlu
proprietate. Acest lucru se realizează utilizând aceeași sintaxă pentru căutarea unui șir cu JavaScript.
De asemenea, apelul pentru funcția de căutare este legat de alte metode de interogare, cum ar fi Unde
, și
, sau
, limită
, fel
, orice
, etc.
Să ne extindem la exemplul precedent pentru a limita rezultatele noastre la primele cinci cărți și pentru a sorta data descoperită la data creată. Aceasta va reveni la cele cinci cărți cele mai recente care conțin "mvc" în titlu.
Book.find (title: / mvc / i) sortați ('- create') .limit (5) .exec (funcția (err, cărți) if (err) throw err; );
După aplicarea aplicației găsi
funcția, ordinea celorlalte funcții nu este importantă deoarece toate funcțiile în lanț sunt compilate împreună într-o singură interogare și nu executat până la Exec
se numește funcția.
Așa cum am menționat mai devreme, findById
este executat un pic diferit. Se execută imediat și acceptă o funcție de apel invers, în loc să permită un lanț de funcții. În acest exemplu, fac o interogare de la un autor specific _id
.
Author.findById ('59b31406beefa1082819e72f', funcția (err, autor) if (err) throw err; console.log (author););
_id
în cazul tău ar putea fi ușor diferite. Am copiat asta _id
de la un precedent console.log
când găsiți o listă de cărți cu "mvc" în titlul lor.
Odată ce un obiect a fost returnat, puteți modifica oricare dintre proprietățile acestuia pentru al actualiza. După ce ați făcut modificările necesare, sunați la Salvați
, la fel ca atunci când creați obiectul. În următorul exemplu, voi extinde findbyId
exemplu și actualizați linkedin
proprietate asupra autorului.
Autor.findById ('59b31406beefa1082819e72f', funcție (err, autor) if (err) throw err; author.linkedin = 'https://www.linkedin.com/in/jamie-munro-8064ba1a/'; autor.save (funcția (err) if (err) throw err; console.log ("Autor actualizat cu succes");););
După ce autorul a fost preluat cu succes, linkedin
proprietatea este setată și Salvați
se numește funcția. Mongoose este capabil să detecteze că linkedin
proprietatea a fost schimbată și va trimite o declarație de actualizare către MongoDB doar pe proprietățile modificate. Dacă a apărut o eroare la salvare, o excepție va fi aruncată și va opri aplicația. Când este reușit, un mesaj de succes este înregistrat în consola.
Mongoose oferă, de asemenea, două funcții suplimentare care fac găsirea unui obiect și salvarea lui într-un singur pas cu funcțiile numite în mod corespunzător: findByIdAndUpdate
și findOneAndUpdate
. Să actualizăm exemplul anterior pentru a utiliza findByIdAndUpdate
.
Author.findByIdAndUpdate ('59b31406beefa1082819e72f', linkedin: 'https://www.linkedin.com/in/jamie-munro-8064ba1a/', functie (err, autor) if (err) throw err; console.log (autor););
În exemplul anterior, proprietățile de actualizare sunt furnizate ca obiect la al doilea parametru al lui findByIdAndUpdate
funcţie. Funcția de retur este acum al treilea parametru. Când actualizarea are succes, autor
obiectul returnat conține informațiile actualizate. Acesta este înregistrat în consola pentru a vedea proprietățile actualizate ale autorului.
În tot acest articol, am oferit fragmente mici de cod care identifică o acțiune foarte specifică, cum ar fi crearea unei scheme, crearea unui model etc. Să le punem împreună într-un exemplu complet.
În primul rând, am creat două fișiere suplimentare: author.js
și book.js
. Aceste fișiere conțin definițiile schemelor respective și crearea de modele. Linia finală de cod face modelul disponibil pentru utilizare în index.js
fişier.
Să începem cu fișierul author.js:
var mongoose = necesită ("mongoose"); var autorSchema = mongoose.Schema (_id: mongoose.Schema.Types.ObjectId, nume: firstName: type: String, required: true, lastName: String, biografie: String, twitter: type: String, validate : validator: funcție (text) retur text.indexOf ('https://twitter.com/') === 0;, mesaj: 'mânerul Twitter trebuie să înceapă cu https://twitter.com/' , facebook: type: String, validate: validator: function (text) retur text.indexOf ('https://www.facebook.com/') === 0; cu https://www.facebook.com/ ', linkedin: type: String, validate: validator: function (text) retur text.indexOf (' https://www.linkedin.com/) === 0;, mesaj: 'LinkedIn trebuie să înceapă cu https://www.linkedin.com/', profilePicture: Buffer, creat: type: Date, default: Date.now); var Autor = mongoose.model ("Autor", autorSchema); module.exports = Autor;
Înainte vine book.js
fişier:
var mongoose = necesită ("mongoose"); var bookSchema = mongoose.Schema (_id: mongoose.Schema.Types.ObjectId, title: String, rezumat: String, isbn: String, thumbnail: Buffer, autor: type: mongoose.Schema.Types.ObjectId, Author ', evaluări: [rezumat: String, detaliu: String, numberOfStars: Număr, creat: type: Date, default: Date.now], creat: type: Date, default: Date.now ); var carte = mongoose.model ("carte", bookSchema); module.exports = Carte;
Și în cele din urmă, actualizată index.js
fişier:
var mongoose = necesită ("mongoose"); var Autor = cer ('./ autor'); var Book = cer ('./ carte'); mongoose.connect ('mongodb: // localhost / mongoose_basics', functie (err) if (err) throw err; console.log ('Succes conectat') var jamieAuthor = autor nou (_id: new mongoose.Types. ObjectId (), nume: firstName: 'Jamie', ultimName: 'Munro', biografie: 'Jamie este autorul ASP.NET MVC 5 cu Bootstrap și Knockout.js.', Twitter: 'https: // twitter .com / endyourif ', facebook:' https://www.facebook.com/End-Your-If-194251957252562/ '); jamieAuthor.save (funcția (err) if (err) throw err; console.log ("Autor: Mongoose.Types.ObjectId"), titlul: "ASP.NET MVC 5 cu Bootstrap și Knockout.js", autor: jamieAuthor._id, evaluări : [rezumat: 'Mare citește'); mvcBook.save (funcția (err) if (err) throw err; (_id: new mongoose.Types.ObjectId (), titlu: 'Knockout.js: Crearea de aplicații web dinamice client-side', autor: jamieAuthor._id); knockoutBook.save (funct ion (err) if (err) arunca eroare; console.log ("Salvați salv."); ); ); );
În exemplul de mai sus, toate acțiunile Mongoose sunt conținute în conectați
funcţie. autor
și carte
fișierele sunt incluse în necesita
după ce a inclus mangustă
bibliotecă.
Cu MongoDB care rulează, puteți rula acum aplicația completă Node.js cu următoarea comandă:
nod index.js
După ce am salvat unele date în baza mea de date, am actualizat index.js
fișierul cu funcțiile de căutare după cum urmează:
var mongoose = necesită ("mongoose"); var Autor = cer ('./ autor'); var Book = cer ('./ carte'); mongoose.connect ('mongodb: // localhost / mongoose_basics', funcția (err) if (err) throw err; console.log ('Succes conectat'); Book.find (title: / mvc / i). sort ('- creat') .limit (5) .exec (functie (err, carti) if (err) throw err; console.log (books); , autor () (if (err) throw err; author.linkedin = 'https://www.linkedin.com/in/jamie-munro-8064ba1a/'; autor.save (functie (err) err; console.log ("Autor actualizat cu succes"););); Autor.findByIdAndUpdate ('59b31406beefa1082819e72f', linkedin: 'https://www.linkedin.com/in/jamie-munro-8064ba1a/' , funcția (err, autor) if (err) throw err; console.log (autor);););
Încă o dată, puteți rula aplicația cu comanda: nod index.js
.
După ce ați citit acest articol, ar trebui să puteți crea scheme și modele Mongoose extrem de flexibile, să aplicați validarea simplă sau complexă, să creați și să actualizați documente și, în final, să căutați documentele create.
Sperăm că acum vă simțiți confortabil folosind Mongoose. Dacă doriți să aflați mai multe, aș sugera revizuirea ghidurilor Mongoose care se ocupă de subiecte mai avansate, cum ar fi populația, middleware-ul, promisiunile etc..
Vânătoarea fericită (referință slabă pe animale Mongoose)!