Blog ENI : Toute la veille numérique !
-25€ dès 75€ sur les livres en ligne, vidéos... avec le code FUSEE25. J'en profite !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Angular et Node.js
  3. Le SGBD NoSQL MongoDB
Extrait - Angular et Node.js Optimisez le développement de vos applications web avec une architecture MEAN (2e édition)
Extraits du livre
Angular et Node.js Optimisez le développement de vos applications web avec une architecture MEAN (2e édition) Revenir à la page d'achat du livre

Le SGBD NoSQL MongoDB

Introduction

MongoDB est un système de gestion de base de données créé en 2007 par la société homonyme (et à l’heure où cet ouvrage est écrit, de version 4.0). Ce SGBD fait partie de la famille NoSQL (Not only SQL) qui regroupe des SGBD non relationnels de différents types. La principale motivation à s’écarter du modèle relationnel est la volonté de s’affranchir des nombreuses contraintes imposées par celui-ci, contraintes qui peuvent devenir gênantes si un accès très rapide à de grands volumes de données est privilégié. Cette efficacité est en partie due à ce que les contraintes d’intégrité et les transactions ACID ne sont pas assurées par MongoDB (elle est aussi due à une création performante et dynamique d’index).

MongoDB stocke les données sous un format binaire appelé BSON (Binary JSon) permettant (à quelques exceptions près) de sérialiser des objets JavaScript en binaire (suivant un format dit clés/valeurs, les objets JavaScript étant eux-mêmes implémentés par des tableaux associatifs). Le mot BSON s’inspire directement de JSON, qui est le format textuel de la sérialisation des objets JavaScript.

Parmi la famille des SGBD NoSQL, MongoDB est classé dans...

Pourquoi utiliser une base de données NoSQL ?

MongoDB a comme principal avantage la capacité de pouvoir gérer un volume très important de données, car une base de données peut être répartie sur plusieurs serveurs tout en assurant des accès efficaces (le SGBD Redis, en gardant les données en mémoire vive, assure des accès encore plus efficaces, mais aux dépens d’une certaine vulnérabilité). Cela dit, ce bénéfice n’est pas forcément celui qui nous intéresse principalement dans le cas du fil rouge (la création d’une application de commerce en ligne), même si une entreprise d’e-commerce peut à terme gérer beaucoup de données, entre les dizaines de milliers de références des produits en vente et la base clientèle.

Par ailleurs, MongoDB s’avère un bon choix dans la gestion de données hétérogènes et quand il est difficile de prédéterminer les attributs des entités à l’origine des tables ou des collections (par exemple, si vous voulez modéliser le contenu des articles d’une encyclopédie en ligne, il serait bien difficile de prélister tous leurs attributs, et si cette liste était faite, il est certain que la majorité de ces attributs n’auraient pas de valeurs...

Présentation de MongoDB

1. Les collections et les documents

Si vous êtes habitué à un SGBD relationnel, une première approximation (très grossière) est de considérer que les tables vont correspondre aux collections, et les tuples aux documents. Cela (mal) dit, il faut tout de suite prendre conscience de ce qui suit :

  • Sous MongoDB, une base de données n’est pas censée être construite suivant un schéma prédéfini (même s’il est possible de le faire par exemple avec l’ODM Mongoose), et donc les tuples ne sont pas censés posséder une liste identique d’attributs.

  • Par ailleurs, MongoDB n’assurant pas la vérification des contraintes d’intégrité, celle-ci doit être effectuée au niveau de la logique métier.

Un point important à bien comprendre est que MongoDB ne permet qu’une gestion partielle des clés étrangères. Si vous voulez identifier un document (que nous appellerons le document cible) d’une collection dans un document (que nous appellerons le document source) d’une autre collection, vous avez deux solutions :

  • La duplication des propriétés du document cible dans le document source, ce qui peut paraître maladroit, mais facilitera les temps d’accès.

  • L’identification du document cible dans le document source...

Mise en œuvre de MongoDB

1. Installation de MongoDB

a. Installation de MongoDB sous Linux

Toutes les informations utiles vous seront données sur ce site : https://docs.mongodb.com/manual/installation/

Et plus particulièrement pour Ubuntu, consultez : https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/

Le lancement du service est effectué par la commande suivante (attention, Systemd est le gestionnaire de services depuis Ubuntu 16.04) :

sudo systemctl enable mongodb 

Pour vérifier quel est le port occupé par MongoDB (il tourne par défaut sur le port 27017) :

sudo netstat -antup 

b. Installation de MongoDB sous Windows ou sous Mac OS

Toutes les informations utiles vous seront données sur ce site : https://docs.mongodb.com/manual/installation/

c. Utilisation de MongoDB en lignes de commande

En lignes de commande, la gestion des bases de données de MongoDB et des collections contenues dans celles-ci s’effectue grâce au mongo shell, qui est une interface JavaScript interactive. Pour cela, il suffit de lancer l’exécutable mongo dans votre terminal ou votre invite de commande :

mongo 

Le mongo shell peut évaluer (presque) n’importe quel code JavaScript et afficher des résultats via sa méthode print() :

var me="Pierre" 
print("Bonjour", me) 

La fonction print() permet d’afficher des messages sur le terminal ou l’invite de commandes.

Dans les exemples qui suivent, les mots encadrés par < et > sont à remplacer par vos propres données :

  • <NomDeLaBase> : nom de votre base MongoDB.

  • <NomDeLaCollection> : nom de votre collection MongoDB.

  • <Document> : un document MongoDB, c’est-à-dire un objet stocké dans une collection.

  • <Collection> : une collection, c’est-à-dire une liste d’objets : [Objet1, ..., Objetn]

  • <ObjetFiltre> : un objet permettant de filtrer une collection MongoDB pour sélectionner les documents correspondant aux critères de recherche.

  • <FichierJSON> : un fichier au format JSON.

2. Affichage de la liste des bases de données

La liste des bases de données est obtenue par l’instruction suivante :

show dbs 

3. Création d’une base de données

La création d’une base de données est obtenue par l’instruction suivante :

use <nom...

Utilisation de MongoDB via Node.js

Pour illustrer l’association entre Node.js et MongoDB, vous allez créer différentes versions d’un serveur Node.js nommé onlinesalesserver.

Ce serveur sera configuré par le fichier package.json.

1. Installation du module MongoDB pour Node.js

 Première étape : créez le squelette du fichier package.json avec la commande npm init.

Par rapport aux demandes d’informations que provoque cette commande, seuls sont renseignés le nom du serveur, sa description, le fichier qui le contient et votre nom.

Voici le fichier package.json ainsi produit :

{ 
  "name": "onlinesalesserver", 
  "version": "1.0.0", 
  "description": "serveur de vente de produits hitech", 
  "main": "onlinesalesserver.js", 
  "scripts": { 
    "test": "echo \"Error: no test specified\" && exit 1" 
  }, 
  "author": "Pierre Pompidor", 
  "license": "ISC" 
} 

 Comme vous avez installé Node.js globalement, interrogez sa version avec node -v, et complétez ce fichier avec la propriété engines. Complétez aussi l’objet scripts avec la propriété start, ce qui permet d’utiliser npm pour lancer le serveur :

{ 
  ... 
  "scripts": { 
    "test": "echo \"Error: no test specified\" && exit 1", 
    "start": "node onlinesalesserver.js" 
  }, 
  ... 
  "engines": { "node": ">= 8.10.0" } 
} 

 Seconde étape : installez les modules express, cors et bien sûr mongodb :

npm install express cors mongodb --save 

L’option --save permet de compléter les dépendances listées dans le fichier package.json.

Voici donc la version (pour l’instant) finale de ce fichier.

{ 
  "name": "onlinesalesserver", 
  "version": "1.0.0", 
  "description": "serveur de produits hitech", 
  "main": "onlinesalesserver.js", ...

Interrogation de MongoDB via les routes gérées par express

Vous allez maintenant interroger votre base de données MongoDB en invoquant le serveur Node.js par des requêtes HTTP qui expriment des routes. Ces routes sont gérées par le module express de Node.js.

1. La structure d’un serveur Node.js interrogeant MongoDB

Un serveur Node.js interrogeant MongoDB implique les actions suivantes :

  • Utilisation du module express :

  • pour créer une application gérant les routes ;

  • et qui écoute sur un port donné.

  • Utilisation du module cors pour permettre le cross-origin resource sharing.

  • Création du client MongoDB qui :

  • se connecte à une base de données gérée par le serveur MongoDB ;

  • met en place des « écouteurs » sur les différentes routes.

Dans l’exemple structurel suivant, <route> désigne une route quelconque.

"use strict"; 
var express=require("express");  // Utilisation du module express 
var app=express();               // pour créer une application express 
app.listen(8888);                // qui écoute sur un port donné 
var cors=require("cors");        // Utilisation du module cors 
 
app.use(cors());     // pour permettre le cross-origin resource sharing 
 
var MongoClient = require("mongodb").MongoClient; 
var url = "mongodb://localhost:27017"; 
var assert = require("assert"); 
 
MongoClient.connect(url, {useNewUrlParser: true}, (err, client) => {  
    let db = client.db("OnlineSales"); 
    assert.equal(null, err);  
    app.get(<route>,  
           (req, res) => { // gestion d'une route (méthode GET)  
                            ...  
    });  
 
    ... // autres gestions de routes via la méthode GET  
 
    app.post(<route>,  
            (req, res) => { // gestion d'une route (méthode POST)  
       ...

Le fil rouge du côté serveur

Voici le moment de créer quelques produits à vendre !

1. Création de la collection

Le but est de créer une collection de test nommée Products à partir du fichier products.json suivant :

   [{ 
  "type":"phone", "brand":"Peach", "name":"topPhone 8 32G", 
  "popularity":4, "price":900, 
  "picture":"topphone8.jpeg", "stock":5 
 }, 
 { 
  "type":"phone", "brand":"Peach", "name":"topPhone 8 64G", 
  "popularity":5, "price":1000, 
  "picture":"topphone8.jpeg", "stock":20 
 }, 
 { 
  "type":"phone", "brand":"Peach", "name":"topPhone 8 256G", 
  "popularity":4, "price":1300, 
  "picture":"topphone8.jpeg", "stock":18 
 }, 
 { 
  "type":"phone", "brand":"Threestars", "name":"bigPhone 9", 
  "popularity":4, "price":700, 
  "picture":"bigphone9.jpeg", "stock":10 
}, 
{ 
  "type": "phone", "brand" : "Konia", "name" : "Konia4000", 
  "picture" : "konia4000.jpeg", "stock":0 
}, 
{ 
  "type":"computer", "brand":"Vale", "name":"Vale 3000", 
  "popularity":4, "price":700, 
  "picture":"vale3000.jpeg", "stock":32 
}, 
{ 
  "type":"computer", "brand":"Peach", "name":"Peach pro", 
  "popularity":5, "price":1300, 
  "picture":"peachpro.jpeg", "stock":8 
}, 
{ 
  "type":"tablet", "brand":"Threestars", "name":"bigTablet", ...

Bilan des acquis de ce chapitre

Utiliser un système de gestion de base de données NoSQL orienté document, et plus particulièrement MongoDB, apporte deux grands bénéfices. Le premier est de pouvoir gérer de grands volumes de données de manière efficace (grâce, entre autres, à la création d’index, mais la vérification des contraintes d’intégrité et le respect des propriétés ACID des transactions ne sont pas assurés), le second étant de pouvoir stocker des documents hétérogènes, c’est-à-dire ne présentant pas forcément entre eux les mêmes propriétés (les documents étant les objets sérialisés JavaScript sous un format binaire dans les collections).

Cette solution est aussi très appréciée dans le cas d’une architecture MEAN mettant en œuvre un serveur Node.js et une application Angular, car elle assure l’homogénéité de la représentation de données (objets JavaScript) et de leur manipulation.

Nous avons expliqué comment installer MongoDB, insérer des documents dans une collection et créer de nouvelles collections. L’interrogation des collections a été étudiée avec soin : la méthode find() spécifie un objet...