Lekce 2 - Real-time kniha návštěv - Databáze a CRUD
V minulé lekci, Real-time kniha návštěv - Příprava prostředí pro projekt, jsme si udělali kratičký úvod do Node.js, seznámili se s novým projektem a nainstalovali si první potřebný balíček pro projekt.
V této lekci se zaměříme na server a jeho přístup do databáze.
Databáze
Pro správu databáze budeme potřebovat software MongoDB Compass, pokud ho
ještě nemáte stáhněte
si ho a nainstalujte. Po úspěšném stažení a instalaci budeme ještě
potřebovat vytvořit nový cluster. Toho docílíme pomocí MongoDB
Atlasu. Na ten se dostaneme zapnutím Compassu a zmáčknutím na
tlačítko Create Free Cluster vpravo:

Klikneme na zelené tlačítko GET STARTED FREE a založíme si
účet. Po registraci bychom měli být na této stránce:

Klikneme vpravo na tlačítko Create a Cluster. Poté budeme
mít na výběr poskytovatele a region. Vyberte libovolně, doporučuji vybrat
nejblíže k vašemu bydlišti, např. Ireland od poskytovatele AWS. Úplně na
konci si budeme moct pojmenovat tento Cluster zdarma. Název budeme vybírat v
seznamu clusterů, ale pokud budeme používat jenom FREE verzi (což v rámci
kurzu budeme), jednoduše cluster rozpoznáme. Nakonec klikneme na tlačítko
dole Create a Cluster. Nyní se nám bude vytvářet a konfigurovat
databáze, což může zabrat několik minut. Po chvilce se vše připraví:

Pro připojení ke clusteru budeme potřebovat tzv.
Connection String. Ten získáme v Atlasu kliknutím na tlačítko
Connect. Nyní si musíme nastavit zabezpečení, kdo se bude moct
připojit do naší databáze. Pro jednoduchost můžeme vložit současnou IP
adresu kliknutím na tlačítko Add Your Current IP Address a poté
potvrdit kliknutím na tlačítko Add IP address. Pokud nemáte
statickou IP od poskytovatele a mění se, budete muset tuto IP neustále měnit
nebo nastavte přístup odkudkoli kliknutím na
Allow Access from Anywhere:

Jako druhý krok musíme vytvořit přihlašovací jméno a heslo. Zvolte dle
libosti ale údaje si někam napište nebo pamatujte. Uživatele vytvoříme
tlačítkem Create Database User. Nakonec můžeme konečně zvolit
metodu pro připojení tlačítkem vpravo dole
Choose a connection method. Klikneme na poslední možnost
Connect using MongoDB Compass a tlačítkem Copy nebo
ručně zkopírujeme Connection String. Zkopírovanou URL vložíme do
Compassu (samozřejmě nezapomeňme nahradit <password> svým
heslem). URL bude vypadat například takto:
mongodb+srv://itnetwork:[email protected]/test
Nyní bychom se měli tlačítkem CONNECT dostat do správy
clusteru. Nyní vytvoříme novou databázi a to přes tlačítko
CREATE DATABASE, pojmenovat ji můžeme jak chceme, já ji
pojmenuji ITnetwork. Druhé textové pole je název pro kolekci
(kolekce v MongoDB je něco jako tabulka v MySQL), tu pojmenujeme třeba
posts. V tuto chvíli nemáme v kolekci posts nic, to
hned napravíme. Klikneme na kolekci posts a poté na tlačítko
ADD DATA > Insert Document vložíme toto:
{ "name": "2tix", "email": "[email protected]", "message": "Ahoj", "date": "26. 1. 2021" }
Dokument vložíme do databáze.
Data jsou uchovávána ve formátu JSON (JavaScript Object Notation). Pokud jsme vše udělali správně, měla by naše kolekce vypadat takto:

Server
Databázi máme sice hotovou, my do ní ale budeme chtít zapisovat z
JavaScriptu. Otevřeme si tedy složku Server v našem projektu a
zde vytvoříme nový soubor server.js. Otevřeme ho a hned na
začátku definujme konstantu url, ta bude uchovávat connection
string z MongoDB (způsob jeho získání bude stejný jako u Compassu, jen
místo Connect using MongoDB Compass, zvolíme
Connect your application):
const url = "mongodb+srv://itnetwork:<password>@itnetworkcluster.y12xk.mongodb.net/<dbname>?retryWrites=true&w=majority";
<password> zase nahradíme svým heslem a u konce
<dbname> nahradíme názvem naší databáze (u mě
ITnetwork):
const url = "mongodb+srv://itnetwork:[email protected]/ITnetwork?retryWrites=true&w=majority";
Pro přístup do MongoDB musíme ještě nainstalovat knihovnu příkazem:
npm i mongodb --save
Teď tuto knihovnu využijeme, uložíme si jí do konstanty:
const MongoClient = require("mongodb").MongoClient;
K databázi se připojíme pomocí:
MongoClient.connect(url,(err,client) => {
});
Funkce connect bere jako první argument Connection
string a jako druhý funkci (callback). Náš callback má také
dva argumenty - err (chybu) a client, přes tento objekt se budeme připojovat k
databázi. Do callbacku vložme následující kód:
MongoClient.connect(url,(err,client) => { if(err) throw err; console.log("Database connected..."); const posts = client.db("ITnetwork").collection("posts"); });
První řádek vyhodí chybu, pokud nějaká je. Druhý nám vypíše, že je
server připojen k databázi a třetí získá kolekci posts z
databáze ITnetwork a uloží ji do konstanty
posts.
Čtení
Pokud zkusíme vypsat kolekci takto:
console.log(posts);
Aplikace vypíše hodně dlouhý objekt, který rozhodně neodpovídá tomu, co v kolekci máme. Pro správný výpis všech dokumentů v kolekci použijeme:
posts.find().toArray((err, data) => { if (err) throw err; for(const doc of data){ console.log(doc); } });
Zde posts.find().toArray() dává funkci, kterou bere jako
argument proměnnou data, tedy list všech dokumentů v kolekci. My
pak ve cyklu for-of vypíšeme všechny tyto dokumenty.
Celý náš kód bude tedy vypadat takto (URL si změňte na svou):
const url = "mongodb+srv://itnetwork:[email protected]/ITnetwork?retryWrites=true&w=majority"; const MongoClient = require("mongodb").MongoClient; MongoClient.connect(url,(err,client) => { if(err) throw err; console.log("Database connected..."); const posts = client.db("ITnetwork").collection("posts"); posts.find().toArray((err, data) => { if (err) throw err; for(const doc of data){ console.log(doc); } }); });
Nyní si aplikaci zkusíme příkazem node server.js ze složky
Server/. Aplikace vypíše něco takového:
Database connected... { _id: 600fd6dc545496255c10b83c, name: '2tix', email: '[email protected]', message: 'Ahoj', date: '26. 1. 2021' }
Všimněme si, že nám MongoDB přidala do dokumentu _id (to
budete mít samozřejmě odlišné), které slouží k indexaci dokumentů.
Ještě než se vrhneme na zápis do databáze, podívejme se blíže na funkci
find(). My ji zde používáme bez parametrů, ale pokud chcete
například zobrazit jen zprávy vytvořené dne 26. 1. 2021,
můžeme zprávy filtrovat:
posts.find({date: "26. 1. 2021"}).toArray((err, data) => { if (err) throw err; for(const doc of data){ console.log(doc); } });
Pokud chceme najít v databázi jen jeden dokument, můžeme použít funkci
findOne():
posts.findOne({date: "26. 1. 2021"}, (err,doc) => { if (err) throw err; if(doc) console.log(doc); else console.log("Document was not found!"); });
Zapisování
Zápis do databáze provedeme metodou posts.insertOne():
posts.insertOne({ name: "John Doe", email: "[email protected]", message: "Ahojky", date: "26. 1. 3021" });
Zkusme znovu zapnout server.js.
Pokud se nyní podíváme do Compassu, můžeme vidět, že se náš dokument
opravdu vložil. Pokud se nový záznam nepřidal, zkuste nejdříve
aktualizovat databázi kliknutím na tlačítko Refresh úplně
napravo v MongoDB Compass.
Editace
Data v databázi budeme upravovat podobně, jako vkládat:
posts.update({ name: "John Doe" }, { $set: { name: "2tix" } });
První argument metody update() je filtr (funguje stejně jako u
metody insert()/insertOne()), druhý je objekt
obsahující další objekt $set, do kterého vždy píšeme, jaký
z atributů dokumentu chceme změnit a na co. Opět zde můžeme použít metodu
updateOne(), jediný rozdíl je, že metoda
updateOne() upraví pouze první nalezený
dokument.
Odstraňování
K odstraňování slouží metoda deleteMany(). Ta je asi
nejjednoduší, protože bere jen jeden argument - filtr (opět úplně stejný
jako u metod update() a insert()):
posts.deleteMany({ name: "2tix" });
A i zde se dá použít metoda deleteOne():
posts.deleteOne({ name: "2tix" });
Funkce then()
Na všech metodách MongoDB
(find()/insert()/update()/delete())
můžeme zavolat funkci .then(), která opět bere jako argument
callback:
posts.deleteOne({name: "2tix"}).then(() => { console.log("Deleted..."); });
Závěr
V této lekci jsme se naučili vytvářet MongoDB databázi a používat CRUD
operace (Create - insert(), Read
- find(), Update - update(),
Delete - delete()). Celý dnešní kód by měl
vypadat následovně:
const url = "connectionString"; const MongoClient = require("mongodb").MongoClient; MongoClient.connect(url, {useUnifiedTopology: true}, (err, client) => { if (err) throw err; console.log("Database connected..."); const posts = client.db("ITnetwork").collection("posts"); posts.find({date: "26. 1. 2021"}).toArray((err, data) => { if (err) throw err; for (const doc of data) { console.log(doc); } }); posts.insertOne({ name: "John Doe", email: "[email protected]", message: "Ahojky", date: "26. 1. 3021" }); posts.updateOne({ name: "John Doe" }, { $set: { name: "2tix" } }); posts.deleteOne({name: "2tix"}).then(() => { console.log("Deleted..."); }); posts.findOne({date: "26. 1. 2021"}, (err,doc) => { if (err) throw err; if(doc) console.log(doc); else console.log("Document was not found!"); }); });
V další lekci, Real-time kniha návštěv - Server, si naprogramujeme náš server v Node.js pomocí Socket.io.

