MongoDB

Najpopularniejsza nierelacyjna baza danych, powstała w 2009, związana z JS. Różnice pomiędzy bazami SQL i noSQL: Twórca Stron "SQL vs noSQL | MySQL vs MongoDB - różnice" [17:18] | Academind "SQL vs NoSQL or MySQL vs MongoDB" [YT 21:29]

Instalacja MongoDB serwer - MongoDB Community Server, pyta czy zainstalować wersję Complete, czy Custom: w Complete jest MongoDB Compass. Trzeba też wybrać lokalizację danych i logów.

Baza danych. W pliku App.js najpierw require mongoose, potem mongoose.connect. Weryfikacja połączenia opisana w dokumentacji.

Nomenklatura:

  • Cluster (w MongoDB Atlas): usługa zdefiniowana w konfiguratorze, w klastrze jest wiele baz danych.
  • Database: pojedyncza baza danych
  • Collection: odpowiednik tabeli SQL, zespół danych zdefiniowany w tzw. modelu
  • Document: pojedynczy zapis, rekord bazy

Shell mongo, polecenie mongo.

MongoDB przechowuje dane wg tzw modeli: schematów danych, opisujących pola, rodzaj danych i czy są wymagane. Modele są trzymane w osobnym katalogu /models, na końcu każdego modelu eksport. Zwyczajowo modele nazywane są z dużej litery.

MongoDB Shell

 db.cars.insertOne({brand: 'Ford', model : 'Taunus'});

Można umieścić wiele w tablicy.

 db.cars.insertMany([{...}, {...}])
 db.cars.find()

Wyszukać, można wg każdego pola danych. Ale ID nie jest stringiem a specyficznym rodzajem obiektu i samo skopiowanie go nie wystarczy, trzeba objąć go funkcją ObjectId("tu numer"). Bez parametrów wylistuje całą kolekcję.

Wyszukanie wg parametrów: większe niż {$gt: parametr}; mniejsze niż {$lt: parametr}, można je łączyć: {$gt:30, $lt:50}. Odpowiednio $lte i $gte oznaczają mniejsze/większe lub równe (equal). {$in [5, 10, 15]} - wyszuka wszystkie z tymi parametrami, przeciwieństwo {$nin [5, 10, 15]} (not in).

OR

 db.clients.find({$or: [{age: {$gt: 20, $lt: 50}}, {active:true}]})

Zaprzeczenie

db.clients.find({age: {$not: {$gt: 20}}})

Modyfikacja, aktualizacja. Polecenie update ma trzy parametry: które dokumenty uaktualnić (jeżeli brak odnosi się do wszystkich), co w nich zmienić, trzeci określa czy wszystkie znalezione, bez tego domyślnie tylko pierwszy.

 db.clients.update({}, {#set: {active: true}}, {multi: true})

updateOne tylko jeden dokument, updateMany wiele (tu nie trzeba parametru {multi: true}).

Usuwanie, wg dowolnego selektora. Dla wielu deleteMany()

 db.clients.deleteOne({selektor})

Create Read Actualise Delete

MongoDB Compass Community

GUI. Kompletna informacja o kolekcjach i dokumentach. Łatwy wizualny, sposób zarządzania bazami. W widoku tabeli dane muszą być spójne, w widoku listy niekoniecznie.

Node.js: mongodb

Instalacja: mongodb jest oficjalną paczką npm, wspieraną przez MongoDB (nieoficjalną, ale bardzo popularną jest mongoose).

 npm i mongodb -S

Połączenie

 const mongo = require('mongodb');

 const client = new mongo.MongoClient('mongodb://host:port', {useNewUrlParser: true});
 
 client.connect(err => {if (err) {console.log(err);}
 else {console.log("Połączenie z bazą");
 // tu wybór bazy i kolekcji
 }});

Domyślny port: 27017.

W programie

 const db = client.db('test'); // wybór bazy

 const cars = db.collection('cars'); // wybór kolekcji
 
 client.close(); // koniecznie na końcu programu

Wszystkie polecenia jak w shellu. Do wyświetlenia używa się metody find i callback z danymi. Pobranie danych z przekształceniem w tablicę:

 clients.find({}).toArray((err, data) => {
  if (err) {console.log(err);}
  else {console.log(data);}
})

Potwierdzenie zapisu:

}, err => {
  if (err) {console.log('Błąd' + err);}
  else {console.log('Wszystko OK');}
}

Pobranie danych z bazy za pomocą process.argv:

 const args = process.argv.splice(2);

Zapisanie głosu w quizie, metoda save(). Wcześniej zaimportowany model i router,

 router.get('/', (req, res) => {
  new Quiz({ title: 'Tytuł pytania', vote: 0}).save()
  res.render("quiz", { title: "Quiz" });
})

Zapis do bazy

 router.get('/', (req, res) => {
  const newsData = new News({
    title,
    description
  })
  newsData.save((err)=>{console.log(err);})
});
res.render('admin/news-form', { title: 'Dodaj news'});

Walidacja: w funkcji zapisującej dane do bazy

 router.get('/', (req, res) => {
  const body = req.body;

  const newsData = new News(body);
  const errors = newsData.validateSync();

errors przekazać w funkcji res.render(). Potem w szablonie:

 if errors.errors !== undefined
 each message in errors.errors
   p=message

Node.js: mongoose

Niektóre metody mongoose wyglądają jak JS, ale mają inne działanie: exec, sort created itd

Odnośniki

Strony

Narzędzia

Artykuły

Expressjs

Youtube

NeDB

Firebase