Mongo DB (Php) Installation et premières impressions

By | 8 mai 2011

Kesako ??!!

MongoDb est un système de gestion de base de données orienté document, il est développé en C++ depuis 2007. Sa première version rendu disponible au public était en 2009. C’est donc un SGBD qui stocke des documents au format BSon, qui dispose comme tout SGBD digne de ce nom, de la possibilité d’indexer des attributs, supporte la réplication et bien plus.

L’installation du serveur (Unix)

Pour l’installation, nous allons donc suivre le quickstart présent sur le site de MongoDB Quickstart Unix. Son installation ne prend pas plus de 5 min. Elle consiste au téléchargement de l’archive, sa décompression, et la  création de liens symboliques, mongod pour lancer le serveur et mongo pour lancer le prompt. Je vous conseille ensuite de tester le bon fonctionnement de MongoDB en démarrant le serveur via bin/mongod. Ouvrez ensuite un prompt MongoDB en exécutant  bin/mongo et exécuter quelques commandes.

Installation du client Php

Nous allons maintenant procéder à l’installation de l’API cliente Php, nous nous référerons au manuel de MongoDB (Using MongoDB inPhp). Pareil que pour l’installation du serveur rien de bien sorcier, il suffit donc de télécharger le driver en utilisant la commande:

sudo pecl install mongo

et de le charger dynamiquement en ajoutant à votre fichier de configuration php cette ligne:

extension=mongo.so

Les premiers essais en Php

// Instanciation de notre interface
$oMongo = new Mongo();

// Selection de la base
$oDb = $oMongo->myDatabase;
// OU
$oDb = $oMongo->selectDb('myDatabase');

// Selection de la collection
$oCollection = $oDb->myCollection;
// OU
$oCollection = $oDb->selectCollection('myCollection');

Explication:

Mongo

Dans un premier temps nous avons instancié notre objet Mongo, nous permettant de communiquer avec la base, par défaut, sans paramètre, l’hôte sera localhost et sans authentification. Nous pouvons considérer notre objet Mongo comme un gestionnaire de bases. C’est à partir de lui que l’on peut par exemple lister les bases présentes sur le serveur, en créer et/ou en supprimer.

En appelant l’attribut « myDatabase » ou la méthode selectDb() qui ont le même effet, nous allons sélectionner une base si elle existe. Si elle n’existe pas elle sera crée automatiquement, attention aux fautes de frappes :p.

La sélection ou la création d’une base retourne un objet MongoDB, ce qui nous amène au paragraphe suivant.

MongoDB

Nous voila donc après l’appel de la méthode selectDb() en possession de $oDb, qui est une instance de la classe MongoDB. Cet objet quant à lui sera le gestionnaire de collections.

Nous pouvons pour nous repérer comparer une collection à une table en MySQL, mais une table qui n’aurait pas de structure défini.

Avec notre objet MongoDB, nous allons pouvoir lister, créer, modifier et supprimer des collections. Mais elle fait encore plus que ça, car elle permet aussi de réparer votre base en appelant la méthode repair(), qui va temporairement faire une copie des données contenues dans la base, supprimer les données corrompues, compacter et supprimer les espaces libres, tout comme optimize le ferait sur une table MySQL.

MongoCollection

MongoCollection est l’objet issu de l’appel à MongoDB::selectCollection(Name), cet objet permet de gérer les données de la base (insert/update/remove), mais aussi de l’interroger en appelant la méthode find(). C’est aussi à partir de MongoCollection que nous allons pouvoir créer des index sur nos attributs, dont des index de type unique permettant de gérer l’unicité de nos documents autre qu’en utilisant l’id affecté à ces derniers par MongoDB lors de l’insertion.

insert/ find / update / remove

Nous allons donc continuer cette découverte de MongoDb en insérant quelques documents en base, et en les interrogeant. Nous allons pour le moment utiliser des documents simples.

$oObject = array( 'nom'    => 'Diev',
                  'prenom' => 'Guillaume',
                  'age'    => 28);
$oCollection->insert($oObject);
var_dump($oObject);

Pour insérer un document il faut donc appeler la méthode insert() d’une instance de MongoCollection qui attend en paramètre un tableau, et un second paramètre facultatif qui est un tableau d’options.

Grâce au var_dump() nous pouvons constater que notre objet est passé par référence à la méthode insert(), un nouveau champ a été ajouté à notre tableau, il s’agit de l’id unique attribué par défaut à un nouvel objet inséré en base, c’est une instance de la classe MongoId à partir de laquelle nous pouvons  récupérer plusieurs informations concernant l’objet associé, comme le timestamp de sa création.

Une chose qui me semble importante à prendre en compte, c’est le fait que les données ne soient pas aussitôt synchronisées sur votre disque dur, et ne le sont que toutes les minutes. Vous pouvez donc potentiellement perdre jusqu’à une minute d’écriture. Si vous ne pouvez pas vous permettre de perdre autant de temps d’écriture, MongoDB lors de l’insertion vous permet de forcer la synchronisation sur le disque en lui passant en second paramètre ce fameux tableau d’options dont je parlais quelques lignes au dessus.

Un exemple permettant de forcer la synchronisation sur le disque dur:

$oObject = array( 'nom'    => 'Diev',
                  'prenom' => 'Guillaume',
                  'age'    => 28);
$oCollection->insert($oObject, array('fsync' => true));
var_dump($oObject);

Récupération de mes objets insérés:

$oCursor = $oCollection->find();
foreach ($oCursor as $obj) {
    echo $obj["prenom"] . "\n";
}

Dans l’exemple ci-dessus, nous demandons à MongoDB de nous retourner tous les documents insérés dans la collection concernée, nous bouclons ensuite sur nos résultats  avec un simple foreach.

Un autre exemple de requête:

$aQuery = array( "prenom" => "Guillaume" );
$oCursor = $oCollection->find($aQuery);
foreach ($oCursor as $obj) {
    echo $obj["prenom"] . "\n";
}

cette fois ci, nous récupérons les documents possédant un attribut prenom, et dont la valeur est égale à Guillaume.

Mettre à jour un document:

$oNewObject = array('$set' => array('prenom' => 'Eric'));
$oCollection->update(array("prenom" => "Guillaume"), $oNewObject);

$aQuery = array( "prenom" => "Eric" );
$oCursor = $oCollection->find($aQuery);
foreach ($oCursor as $obj) {
    echo $obj["prenom"] . "\n";
}

Pour modifier un document il faut utiliser la méthode update() de MongoCollection. Cette méthode prend en premier paramètre la requête permettant d’identifier les documents concernés par la modification, et le second tableau les modifications à effectuer. Par défaut même si plusieurs documents correspondent aux critères de sélection de la requête, un seul document sera affecté.

Comportement que je trouve bizarre d’ailleurs :p.

Néanmoins MongoDB nous permet de modifier ce comportement en passant en argument un troisième tableau d’options, dans lequel nous pouvons préciser de modifier tous les documents correspondant, et aussi une autre option permettant de demander à MongoDB de créer le document si aucun ne correspond à la requête.

La méthode remove() fonctionne à quelques choses près de la même manière que la méthode update(). Le seul paramètre qui diffère est le tableau d’options, dans lequel cette fois-ci nous pouvons demander à MongoDB de ne supprimer qu’un seul document parmi tous ceux qui correspondent.

MongoCursor

MongoCursor est l’objet retourné par l’appel à la méthode find() de MongoCollection. Cet objet permet d’itérer et manipuler les résultats obtenues par la requête exécutée, d’en limiter le nombre et de les trier. MongoCursor dispose d’une méthode explain() dont je vais me faire le plaisir d’utiliser, comme avec MySQL nous allons pouvoir essayer de comprendre les différents comportement de notre SGBD et ainsi d’optimiser nos requêtes.

Je ne vais pour le moment pas aller plus loin avec MongoDB dans cet article, car il ne s’agit que d’une présentation. Mais je vais porter un des mes projets sur ce système de gestion de base données, afin de continuer de le découvrir,  utiliser les index, pousser l’utilisation de la méthode find() qui à l’air d’offrir une multitude de possibilités et aussi explain() 🙂

Conclusion

Comme vous avez pu le constater MongoDB est très rapide à prendre en main, aucun langage de requête supplémentaire à apprendre. Ils ont réellement cherché à le rendre simple d’utilisation, peut être trop des fois, comme la création automatique des bases et collections que je trouve inutile, et peut induire en erreur.

Niveau performance, ne l’ayant pas benché je ne peux pas me prononcer. Je vais le tester très prochainement en lecture/écriture, comparer ses résultats à ceux que j’obtiendrai avec une base MySQL en vitesse d’exécution mais aussi en charge serveur.

  • Pingback: MongoDB seconde partie | Développeur LAMP()

  • Merci beaucoup pour ces informations très claires.
    Déroutante cette façon de fonctionner, on a du mal à y croire tellement c’est simple.
    Mais je vais essayer de m’intéresser à des cas de figures complexes, pour voir si tout est rose (ou pas).