Vous êtes sur la page 1sur 11

TP MongoDB

TP MongoDB

Khaled Jouini / Abdelweheb GUEDDES

2022-2023

Objectifs du TP
Le TP aborde les points suivants :
1. Familiarisation avec un système NoSQL
2. Familiarisation avec les concepts de réplication et sharding
3. Prise en main de la logique Map/Reduce
4. Mise en place d’un cluster MongoDB

Sommaire
1 MongoDB 2
1.1 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 Import d’un fichier . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Shell Mongo & Map/Reduce . . . . . . . . . . . . . . . . . . . . . . . 2
1.3.1 Shell Mongo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3.2 Requêtes Mongo . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3.3 Jointure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2 Driver Java 4
2.1 Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2 Création d’un client et connexion au serveur . . . . . . . . . . . . . . 4
2.3 Insertion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.4 Interrogation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.5 Mise-à-jour et suppression . . . . . . . . . . . . . . . . . . . . . . . . 6

3 Driver NodeJS 6

4 Interface RESTHeart 7

5 Création d’un cluster MongoDB 8


5.1 Réplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
5.2 Sharding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
5.3 Sharding et réplication .................................................................................... 10

Jouini / Gueddes © 2/11


TP MongoDB

Exercices
1 MongoDB
1.1 Installation
• MongoDB est un système libre de droits (pour sa version communautaire),
téléchargeable à l’adresse http://www.mongodb.org/downloads (ou https://www.
mongodb.org/dl/win32/i386 pour les machines 32 bits).

• Après le téléchargement (il vaut mieux choisir la version 3.2.22) et la


décompression, exécutez le programme d’installation. Vous obtenez un répertoire
mongo, agrémenté du numéro de version et autres indicateurs. Nous le
désignerons par mongodir.

• Ajoutez mongodir/bin dans la variable d’environnement PATH

• Pour lancer le serveur il suffit de taper la commande mongod (se placer sous
mongodir/bin si ce chemin n’a pas été ajouté à PATH)

• Si tout se passe bien vous le serveur se met à l’écoute sur le port 27017 et vous
obtenez le message suivant :
[initandlisten] waiting for connections on port 27017

1.2 Import d’un fichier


• Téléchargez la collection movies

• Dans une autre fenêtre, importer le fichier movies.json avec la commande ci-
après. La commande importe les documents contenus dans le fichier movies.json
dans la collection movies de la base dbtp. Notez que vous n’avez pas besoin de
créer ni la collection ni la base avant d’exécuter la commande. L’argument
jsonArray de la commande indique à l’utilitaire d’import qu’il s’agit d’un
tableau d’objets à créer individuellement, et non d’un unique document JSON.
mongoimport -d dbtp -c movies - -file c:\movies.json - -jsonArray

1.3 Shell Mongo & Map/Reduce


1.3.1 Shell Mongo
Il vous faut maintenant un client pour envoyer les requêtes au serveur mongdb. Vous
pouvez utiliser soit l’interpréteur de commandes de mongo, soit un client graphique
(Il existe plusieurs clients graphiques, le plus répandu étant Compass).

Jouini / Gueddes © 3/11


TP MongoDB

• Pour lancer l’interpréteur de commandes tapez mongo 1 dans l’invite de com-


mandes.

• La base par défaut s’appelle test. Pour se placer dans la base dbtp tapez use
dbtp.

• Insérez quelques documents dans la collection (voir cours)

1.3.2 Requêtes Mongo


Exécuter les requêtes (find() ou Aggregation Pipeline selon le cas) permettant de :
a faire seance proch 1. Compter les films dans lesquels joue l’acteur ”DiCaprio”

2. Compter le nombre de films par acteur

3. Compter le nombre d’acteurs dirigés par chaque réalisateur

4. Compter le nombre de films dont le genre est soit ”Thriller” soit ”drama”.

5. Afficher les titres des films du genre ”drama” par année

6. Trouver le nombre de films dans lesquels a joué ”Clint Eastwood” et parus


avant l’année 2000.

7. Compter les films par genre

8. Compter le nombre de films par acteur

9. Afficher les titres des films du genre ”drama” par année


Pour les 3 dernières requêtes, essayez de les faire avec Map/reduce.

1.3.3 Jointure
Import de données Téléchargez les fichiers artists https://www.dropbox.com/
s/wxr2ek9nn8ru8kp/artists.json?dl=0 et moviesAvecRef https://www.dropbox.
com/s/edasp00vrbailwh/moviesAvecRef.json?dl=0 et insérez les données dans la
base comme suit
mongoimport -d dbtp -c artists --file artists.json --jsonArray
mongoimport -d dbtp -c moviesRef --file moviesAvecRef.json --jsonArray

Ecrivez les requêtes permettant de :


1. Trouvez les titres des films réalisés par ”Quentin Tarantino”.

2. Afficher pour chaque film, les informations sur son réalisateur.

3. Afficher pour chaque réalisateur les titres de ses films.


1
Interpréteur de commandes mongo : un interpréteur Javascript (ce qui est cohérent avec la
représentation JSON). On peut donc lui soumettre des instructions en Javascript, ainsi que des
commandes propres à MongoDB.

Jouini / Gueddes © 4/11


TP MongoDB

2 Driver Java
2.1 Configuration
1. Téléchargez la version 3.2.2 ou une version ultérieure du driver Java de Mon-
goDB (https://oss.sonatype.org/content/repositories/releases/org/
mongodb/mongodb-driver/3.2.2/)
2. Téléchargez mongodb-driver-core (https://oss.sonatype.org/content/repositories/
releases/org/mongodb/mongodb-driver-core/3.2.2/)

3. Téléchargez la version 3.2.2 de la bibliothèque MongoDB permettant de ma-


nipuler les documents BSON (https://mvnrepository.com/artifact/org.
mongodb/bson/3.2.2)

4. Téléchargez la bibliothèque Google Gson (http://repo1.maven.org/maven2/


com/google/code/gson/gson/2.8.1/)2.
5. Sous NetBeans, créez une nouvelle application ”simpleMongoClient” de type
Java SE. Ajoutez le driver MongoDB, Bson et Gson au classpath de votre
projet.

2.2 Création d’un client et connexion au serveur


La création d’un client et la connexion à une base de données à partir du programme
Java se fait avec les instructions ci-après

MongoClient client = new MongoClient("localhost", 27017);


MongoDatabase database = client.getDatabase("dbtp");
MongoCollection<Document> collection = database.getCollection("movies");
Nota Bene : Si la connexion se fait à un cluster MongoDB distribué (et éventuellement
répliqué), il suffit de remplacer l’adresse et le port du serveur mongod par celui du
routeur mongos.
De la même manière si le serveur est répliqué et qu’il fait partie d’un ReplicaSet,
le client doit connaı̂tre les différentes adresses des différents membres du replicaSet
(si le client ne parvient pas à communiquer avec l’un des membres, il doit pouvoir
connaı̂tre les adresses des autres pour pouvoir bénéficier de la réplication).

MongoClient client = new MongoClient(


Arrays.asList(new ServerAddress("localhost", 27017),
new ServerAddress("localhost", 27018),
new ServerAddress("localhost", 27019)));
Vous pouvez tester la connexion à partir de votre client avec l’instruction ci-
après. Il s’agit d’envoyer la commande ping soua la forme d’un document JSON.
Si tout se passe bien la commande ping devrait retourner le document JSON :
{ok=1.0} 3.
2
Gson est une bibliothèque open source développée par Google pour sérialiser/déséréaliser un
objet Java en un document Json
3
Il y a d’autres méthodes bien plus sophistiquées pour tester la disponisbilité de MongoDB.

Jouini / Gueddes © 4/11


TP MongoDB

Document ping = database.runCommand(new Document("ping", 1));


if((double)ping.get("ok")==1.0)){...}else{...}

2.3 Insertion
La création d’un document MongoDB peut se faire soit avec la classe Document
fourni par MongoDB soit avec la bibliothèque Gson de Google. Les 2 méthodes sont
illustrées ci-après. Un objet de type Document dispose d’une méthode append()
permettant d’ajouter un champ au document JSON. Un objet Gson permet de
sérialiser un objet Java en un objet String formaté selon JSON. Les 2 méthodes sont
équivalentes et donnent un même résultat.
// Insertion d’un document : première méthode
Document document = new Document(" id", 200).append("title", "Logan");
collection.insertOne(document);

// Insertion : deuxième méthode


Gson gson = new Gson();
Movie movie = new Movie("movie:100", 2017, "Logan");
collection.insertOne(Document.parse(gson.toJson(movie)));

// Remplacer un document
document.append("director", new Document(" id", "a:1").append("fname","john"));
collection.replaceOne(Filters.eq(" id", document.get(" id")), document);
Il est également possible d’utiliser l’instruction collection.add(Document d)
pour insérer un document d et la commande collection.insertMany(ArrayList<Document>
listDocs) pour l’insertion d’un ensemble de documents.

2.4 Interrogation
Parcours des résultats MongoDB ne dispose pas d’un langage de requêtes stan-
dard (à l’instar de SQL). Cependant il offre plusieurs méthodes pour l’interrogation
d’une collection. La méthode de base pour l’interrogation est find(). La méthode
find() retourne les documents recherchés dans un curseur (semblable au ResultSet
de JDBC). Le parcours du curseur se fait comme suit.
Document myDoc = new Document();
MongoCursor<Document> cursor = collection.find().iterator();
try {
while (cursor.hasNext()) {
myDoc = cursor.next();
System.out.println(myDoc.toJson());
}
}
finally {
cursor.close();
}
Alternativement, il est possible de récupérer le résultat d’un find dans un tableau

Jouini / Gueddes © 5/11


TP MongoDB

List<Document> myDocs = new ArrayList<>();


collection.find().into(myDocs);
System.out.println(myDocs.get(0).toString());
Pour ne retourner qu’un seul document il suffit d’utiliser la méthode first()
myDoc = collection.find().first();

Utilisation des filtres La méthode find() accepte plusieurs types de filtre de


sélection, tels eq (equal), gt (greater than), lt (lower than), etc. Cette méthode
accepte aussi les expressions régulières et les opérateurs booléens. Ci-après quelques
exemples de requêtes MongoDB.

//Trouver un film dont le champ "year" est égal à 2017


myDoc = collection.find(eq("year", 2017)).first();
System.out.println(myDoc.toJson());
//Trouver un film dont le champ "year" est entre 2000 et 2017
myDoc = collection.find(and(gt("year", 2000), lte("year", 2017))).first();
System.out.println(myDoc.toJson());
//Trouver un film dont le champ summary contient la cha^ıne "police"
myDoc = collection.find(myDoc = collection.find(Filters.regex("summary",
"police")).first();
System.out.println(myDoc.toJson());

Projection Lors que tous les champs ne sont pas utiles, il est possible de faire
l’équivalent d’une projection SQL

Document proj= new Document(" id", 1).append("title", 1);


myDoc = collection.find().projection(proj).first();
System.out.println(myDoc.toJson());

2.5 Mise-à-jour et suppression


Il y a différentes fonctions pour la mise-à-jour de documents, les plus communes sont
updateOne() et updateMany().
collection.updateOne(eq(" id", "movie:100"), set("title", "vertigo"));
collection.updateMany(eq("genre", "SF"), set("genre", "Science Fiction"));
L’opération de suppression suit le même principe que la mise-à-jour. Nous avons
également ici deux méthodes : deleteOne() et deleteMany(). La fonction drop()
permet de supprimer une collection (et ses index).
collection.drop();

3 Driver NodeJS
Lorsque vous utilisez NodeJS comme serveur BackEnd, une pratique largement
répandue consiste à stocker les données dans une base MongoDB. Dans la suite

Jouini / Gueddes © 6/11


TP MongoDB

nous illustrons ceci par un exemple simple (cette partie peut être ignorée si vous
n’êtes pas intéressé par NodeJS et la fameuse MEAN Stack).

1. Installez la dernière version de NodeJS sur https://nodejs.org/en/

2. Installez le package mongodb en tapant la commande ci-après dans le shell


Node
npm install mongodb --save

3. Créez un fichier javascript ”test.js” avec le contenu ci-après (vous pouvez


utiliser l’éditeur de votre choix).

var MongoClient = require(’mongodb’).MongoClient;


var url = "mongodb://localhost:27017";
//Si c’est un RS : var url = "mongodb://localhost:27017,localhost:27017"

MongoClient.connect(url, function(err, database){


if (err) throw err;
console.log("Connexion établie");
var db = database.db(’dbtp’);

var o = { id: 1, name: "Foulen" };

db.collection("users").save(o, function(err, res) {


if (err) throw err;
console.log("Doc inséré || id: " + o. id + ", name: " + o.name);
});

db.collection("users").update(
{ id: o. id},
{ $set: { name: "TOTO" }
});

db.collection("users").findOne( { id:o. id }, function(error, res) {


if (error) throw error;
console.log(
"Doc maj || id: "+ res. id +", name: "+ res.name
);
});
database.close();
});

4. Sous le shell node, tapez la commande suivante pour exécuter votre script
node test.js

4 Interface RESTHeart
A l’image de plusieurs systèmes NoSQL comme couchDB et plus récemment SQL
comme Oracle, MongoDB offre une interface REST via RESTHeart. Pour le tester,
téléchargez la version la plus récente à l’url https://github.com/SoftInstigate/
RESTHeart/releases. Cette interface REST pourrait être utile si par exemple vous
voulez accéder à MongoDB directement à partir d’Angular (sans passer par Node)
ou si vous ne voulez pas manipuler le langage propriétaire de MongoDB.

Jouini / Gueddes © 7/11


TP MongoDB

1. Pour lancer RESTHeart tapez la commande ci-après (placez vous avant sur le
répertoire ou vous avez décompressé l’archive)
java -server -jar restheart.jar

2. Utilisez un client cUrl ou postman pour envoyer des requêtes à votre base Mon-
goDB. Par exemple la commande ci-après retourne le document { id:”movie:1”}
de la collection movies de la base dbtp
curl http://localhost:8080/dbtp/movies/movie:1

3. Trouvez le film dont le titre est ”Vertigo”


http://localhost:8080/dbtp/movies/?filter={"title":"Vertigo"}

4. Pour plus d’exemple reportez vous à http://restheart.org/try.html. A


vous de jouer!

5 Création d’un cluster MongoDB


5.1 Réplication
1. On crée deux instances du serveur sur la même machine, avec une base chacun.
cd dbtp; mkdir noeud1; mkdir noeud2

2. Lançons maintenant les 2 serveurs, chacun sur un port. Ils forment le Replica
Set rs00.
mongod --port 27017 --replSet rs00 --dbpath c:\dbTp\noeud1
mongod --port 27018 --replSet rs00 --dbpath c:\dbTp\noeud2

3. Connectons un client au premier serveur.


mongo --port 27017

4. Et initialisons le RS
rs.initiate()

5. On peut alors ajouter le second noeud (remplacer localhost par le nom de la


machine).
rs.add("localhost:27018")

6. db.isMaster() : indique s’il s’agit du primary

7. rs.status() : informations complètes sur le replica set

8. Test d’insertion
use dbtp;
db.colTest.insert ({" id": 1, "nom": "foulen"})

9. On devrait trouver le document sur l’esclave


mongo --port 27018
use dbtp;
db.colTest.find ()

Jouini / Gueddes © 8/11


TP MongoDB

10. Que se passe-t-il? Et après rs.slaveOk()? Pourquoi donc?

11. Tuons notre maˆıtre.


use admin
db.shutdownServer()
Question : le second va-t-il s’élire maı̂tre?

12. Relancer le premier serveur. Que se passe-t-il?

13. Répéter l’expérience en ajoutant un troisième noeud.


mkdir noeud3
mongod --port 27019 --replSet rs00 --dbpath c:\dbTp\noeud3
Connectez vous au maˆıtre et tapez
rs.add("localhost:27019")

5.2 Sharding
1. Lancez un premier shard MongoDB
mongod --port 27018 --dbpath c:\noeud1 4

2. Lancez un deuxième shard MongoDB


mongod --port 27019 --dbpath c:\noeud2

3. Créez un ConfigServer
mongod --configsvr --port 27020 --dbpath c:\confdb

4. Lancez un routeur Mongos


mongos -configdb localhost:27020 --chunkSize 1

5. Connectez vous au mongos et indiquez quelle collection est à partitionner

1 mongo --port 27017


2 > sh.addShard("localhost:27018")
3 > sh.addShard("localhost:27019")
4 > sh.enableSharding("dbtp")
5 > sh.shardCollection("dbtp.dblp", {" id":1})

6. importez les données du fichier dblp et testez si le sharding a bien eu lieu


mongoimport -d dbtp -c dblp --port 27018 --file c:\dblp.json --jsonArray
4
A partir de la version 3.4 il faut ajouter le rôle des serveurs dans le cluster
mongod –shardsvr –port 27018 –replSet rs01 –dbpath c:\noeud1
mongod –shardsvr –port 27019 –replSet rs01 –dbpath c:\noeud2

Jouini / Gueddes © 9/11


TP MongoDB

5.3 Sharding et réplication


La création d’un cluster MongoDB, commence généralement par un seul Shard qui
est le plus souvent un replica set complet. Puis, si la quantité de données à traiter
devient importante, d’autres shards sont ajoutés au cluster (le plus souvent, prenant
chacun la forme d’un replica set). Pour créer les shards, il est nécessaire de créer
au préalable un Config Server pour stocker les informations sur la répartition des
chunks entre les shards.
Dans la suite nous créons tout d’abord un Replicat Set rs01, composé par
deux serveurs mongod. Ensuite, nous importons la collection movies dans le noeud
primary du replica set (les données seront automatiquement repliquées dans le noeud
secondary).
Pour le sharding, nous créons tout d’abord un ConfigServer. Ensuite un
deuxième shard composé d’une seule instance mongod est créé. Les 2 shards sont
enfin associés pour composer un cluster MongoDB.

• Création des répertoires pour les différents serveurs (n1, n2, n3 resp pour les
shards. Configdb pour le répertoire de sharding)
C:\ > cd dbTp

C:\dbTp>mkdir n1
C:\dbTp>mkdir n2
C:\dbTp>mkdir n3
C:\dbTp>mkdir configdb

• Création du ReplicaSet rs01 avec un master et un slave

C:\ mongod --port 27018 --replSet rs01 --dbpath c:\dbTp\n1


C:\ mongod --port 27019 --replSet rs01 --dbpath c:\dbTp\n2
5

C:\\ mongo --port 27018


>rs.initiate()
>db.isMaster()
>rs.add("home:27019") (Remplacez home par le nom de votre machine)

mongoimport -d dbtp2 -c movies --port 27018 --file c:\movies.json --jsonArray

C:\ >mongo --port 27019


rs01:SECONDARY> use dbtp2
r01:SECONDARY> rs.slaveOk()
rs01:SECONDARY> db.movies.findOne()

5
A partir de la version 3.4 il faut ajouter le rôle des serveurs dans le cluster
mongod –shardsvr –port 27018 –replSet rs01 –dbpath c:\dbTp\n1
mongod –shardsvr –port 27019 –replSet rs01 –dbpath c:\dbTp\n2

Jouini / Gueddes © 10/11


TP MongoDB

• Lancement d’un deuxième shard (le premier et le replicaSet rs01)


C:> mongod --dbpath c:\dbTp\n3 --port=270216

• Sharding : lancement d’un config server


C:\mongod --configsvr --dbpath c:\dbTp\configdb --port 27020

• Lancement d’un mongos. Le paramètre chunkSize determine la taille des


chunk. Dans un environnement de production, il est préférable de laisser la
valeur par défaut (64). (A partir de la version 3.4 l’option –chunksize a été
enlevée)
C:\mongos -configdb home:27020 --chunkSize 1

• Connexion au mongos et ajout des shards


mongo --port 27017
sh.addShard( "rs01/home:27018,home:27019" )
sh.addShard("home:27021")
sh.enableSharding("dbtp2")
sh.shardCollection("dbtp2.movies", {" id":1})
sh.status()

6
A partir de la version 3.4 il faut ajouter le rôle des serveurs dans le cluster
mongod –shardsvr –port 27018 –dbpath c:\dbTp\n3

Jouini / Gueddes © 11/11

Vous aimerez peut-être aussi