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.