SlideShare une entreprise Scribd logo
1  sur  68
Télécharger pour lire hors ligne
hello $Mongo
Introduction à MongoDB
Gérald Croës
http://croes.org/gerald/blog/
@geraldcroes
Cédric Derue
@cderue
http://www.croes.org/gerald/conf/php/lille/2011/helloMongo.pdf
Il est encore temps de quitter
la salle...
● Pas de schéma
● Non transactionnel
● Pas de jointures
● Pas de contrainte d'intégrité
● Pas de SQL
● Peu d'intégration avec des outils d'entreprise
● Limité à 2Go <- Version 32bits
... ou alors de rester
● Facilité
● Rapidité
● Scalabilité
● Pas de limitation (64bits)
● Disponible sur la plupart des plateformes
Plan
● Intro : Persistance des données
● Partie 1 : Développement d'une application de gestion de conférence
● Partie 2 : Mongo & ODM (Doctrine)
● Partie 3 : Index
Persistance des données
Persistance des données
Pourquoi une base de
données ?
● Lecture
● Ecriture
● Concurrence
d'accès
● Recherche
efficace
● Interopérabilité
La réponse MongoDB
● Lecture / Ecriture des données très rapide
● Base de données orientée Document
● Format JSON / BSON
● Scalabilité horizontale
Le cas du blog relationnel...
Utilisateur
-------------------
Nom
Prénom
Blog
----------------------
Nom
Commentaires
----------------------
Texte
Date
Articles
----------------------
Texte
Date
Tags
----------------------
Nom
Utilisateur_Articles
--------------------------
id
id
Le cas du blog {Documents}
Utilisateur
-------------------
Nom
Prénom
Blog
----------------------
Nom
Articles
----------------------
Texte
Date
Commentaires
----------------------
Texte
Date
Tags
----------------------
Nom
Cohésion avec le modèle Objet
Petit lexique non illustré
Relationnel MongoDB
Base de données Base de données
Table Collection
Index Index
Enregistrement Document
Colonne Champ / Propriété
Clé étrangère Référence
Jointures Documents embarqués
Clé primaire ObjectID
ORM ODM
Installation de MongoDB
● Téléchargement
wget http://fastdl.mongodb.org/linux/
mongodb-linux-x86_64-2.0.1.tgz
tar xzf mongodb.tgz
● Répertoire de données
sudo mkdir -p /data/db
sudo chown `id -u` /data/db
● Lancement
mongodb/bin/mongod
Installation du driver PHP
pecl install mongo
extension = mongo.so | php_mongo.dll
Un premier document
use phptour
conference = {
titre : "hello $Mongo;",
lieu : "Salle de conférence 1"
}
db.evenements.save(conference)
Un premier document -
recherche
db.evenements.find()
{
"_id" : ObjectId("xxxxxxxxxxx"),
"titre" : "hello $Mongo;",
"lieu" : "Salle de conférence 1"
}
Un identifiant _id généré automatiquement
Qu'avons nous donc ?
show dbs
local (empty)
phptour
test (empty)
show collections
evenements
system.indexes
Premiers constats
● Bases de données dynamiques
● Collections dynamiques
● Enregistrements ajoutés sans contrainte
● JSON
Pas de schéma préalable
JSon ?
JSON = JavaScript Object Notation
{
'langage' : {
'nom' : 'json',
'points_forts' : ['lisible',
'souple',
'intégré',
'compact']
}
}
<?php
echo json_encode(
array(
'language'=>array(
'nom' => 'json',
'points_forts' => array(
'lisible',
'souple',
'intégré',
'compact'
)
)
)
);
//json_decode
BSon - Binary JSon
● Une surcouche de JSon
● Plus rapide à lire / écrire
○ Ecriture des entiers tels que
○ Informations supplémentaires de taille
Retour au document - PHP
//connection à la base de données
$ct = new Mongo();
//Sélection de la base phptour
$db = $ct->phptour;
//Sélection de la collection conferences
$evenements = $db->evenements;
$conferenceMongo = array('titre' => 'hello $Mongo;',
'lieu' => 'Salle de conférence 1');
$evenements->insert($conferenceMongo);
Les objets Mongo (1/2)
● Mongo
○ Connexion à la base
○ close(), connect(), listDBs(), selectDB(),
selectCollection()
● MongoDB
○ Base de données
○ createCollection(), selectCollection(),
createDBRef(), getDBRef(), drop(),
getGridFS()
Sélection des données - PHP
//Sélection du contenu de la base
foreach ($evenements->find() as $document) {
echo "{$document['titre']} ({$document['_id']})nr";
}
//Sélection d'un seul élément
$document = $evenements
->findOne(array('_id'=>new MongoId
('xxxxx')));
//Sélection du seul titre de la conférence
$document = $evenements
->findOne(array('_id'=>new MongoId('xxxxx')),
array('titre'));
Les objets Mongo (2/2)
● MongoCollection
○ Collection
○ count(), find(), findOne(), insert(), remove(),
save(), update()
● MongoCursor
○ Curseur sur résultat de requête
○ getNext(), count(), hint(), limit(), skip(), sort()
Modification du schéma
//Remplacement de tout le document
db.evenements.update(
{titre : "hello $Mongo;"},
{titre : "hello $Mongo;",
lieu : "Salle de conférence 1",
date : ISODate('2011-11-24 10:15:00')
}
)
//Utilisation d'opérateurs
db.evenements.update(
{titre : "hello $Mongo;"},
{$set : {date : ISODate('2011-11-24 10:15:00')}}
)
Les opérateurs de
modification
● $set - ajout d'une propriété
● $unset - suppression d'une propriété
● $inc - incrémenter la valeur d'une propriété
numérique
● $rename - renommer une propriété
Modification du schéma -
PHP
$ct = new Mongo();
$evenements = $ct->phptour->evenements;
$evenements->update(
array('titre'=>'hello $Mongo;'),
array('titre'=>'hello $Mongo;',
'lieu'=>'Salle de conférence 1',
'date'=>new MongoDate(strtotime('2011-11-24 10:
15:00'))));
//Utilisation d'opérateurs
$evenements->update(
array('titre'=>'hello $Mongo;'),
array('$set'=>array('date'=>new MongoDate(strtotime
('2011-11-24 10:15:30'))))
);
Quelques données supplémentaires
$keynote = array('titre' => "Keynote d'ouverture",
'lieu' => 'Auditorium', 'date'=>new MongoDate(strtotime('2011-11-24 9:
00:00')),
'type'=>'Keynote', 'minutes'=>30);
$repas = array('titre' => "Repas",
'date'=>new MongoDate(strtotime('2011-11-24 12:45:00')),
'type'=>'Pause', 'minutes'=>60);
$pauseMatin = array('titre' => "Pause",
'date'=>new MongoDate(strtotime('2011-11-24 11:00:00')),
'type'=>'Pause', 'minutes'=>15);
$pauseAM = array('titre' => "Pause",
'date'=>new MongoDate(strtotime('2011-11-24 15:30:00')),
'type'=>'Pause', 'minutes'=>15);
$evenements->insert($keynote);
$evenements->insert($repas);
$evenements->insert($pauseMatin);
$evenements->insert($pauseAM);
Deuxième constat
Données qui n'ont pas la même structure
● type
● lieu
● minutes
Requêtes type
> db.evenements.distinct("type");
["Keynote", "Pause"]
> db.evenements.distinct("minutes", {type : "Pause"})
[60, 15]
> db.evenements.find({type : "Pause"}).count()
3
> db.evenements.group({
... key : { minutes : true},
... cond : { type : "Pause" },
... reduce : function (obj, prev) { prev.nb += 1; },
... initial : {nb : 0}
... });
[ { "minutes" : 60, "nb" : 1 }, { "minutes" : 15, "nb" : 2 } ]
Requêtes type - PHP
$ct->phptour->command(array('distinct'=>'evenements', 'key'=>'type');
$ct->phptour->command(array('distinct'=>'evenements', 'key'=>'minutes',
'query'=>array('type' => 'Pause'));
$evenements->find(array('type'=>'Pause'))->count();
$evenements->group(
array('minutes'=>1),
array('nb'=>0),
'function (obj, prev) { prev.nb += 1; }',
array('type'=>'Pause')
);
Opérateurs de requête (1/2)
$lt <
$lte <=
$gt >
$gte >=
> db.evenements.find({minutes : {$gte : 30}})
{ "_id" : ObjectId("4ebf87db945630cc0a000000"), "titre" : "Keynote
d'ouverture", "lieu" : "Auditorium", "date" : ISODate("2011-11-24T08:00:
00Z"), "type" : "Keynote", "minutes" : 30 }
{ "_id" : ObjectId("4ebf87db945630cc0a000001"), "titre" : "Repas", "date" :
ISODate("2011-11-24T11:45:00Z"), "type" : "Pause", "minutes" : 60 }
Opérateurs de requête (2/2)
$exists
$or
$nor
$and
$mod
$ne
$in
$nin
$all
Exemples opérateurs
//PHP
$evenements->update(
array('type'=>array('$exists'=>false)),
array('$set'=>array('type'=>'Conference', 'minutes'=>45))
);
//Mongo
> db.evenements.find({minutes : {$in : [30, 15]}})
{ "_id" : ObjectId("4ebf87db945630cc0a000000"), "titre" : "Keynote
d'ouverture", "lieu" : "Auditorium", "date" : ISODate("2011-11-24T08:00:
00Z"), "type" : "Keynote", "minutes" : 30 }
{ "_id" : ObjectId("4ebf87db945630cc0a000002"), "titre" : "Pause", "date"
: ISODate("2011-11-24T10:00:00Z"), "type" : "Pause", "minutes" : 15 }
{ "_id" : ObjectId("4ebf87db945630cc0a000003"), "titre" : "Pause", "date"
: ISODate("2011-11-24T14:30:00Z"), "type" : "Pause", "minutes" : 15 }
Propriétés multivaluées
● Nouvelle table
● Jointures
● Clefs étrangères
● Contraintes d'intégrité
● Modification des
services
Ajout de tags
conference_atoum = {
type : 'Conférence',
titre : 'Atoum',
date : ISODate('2011-11-24 15:45:00'),
minutes : 45,
tags : ['Industrialisation', 'Tests Unitaires', 'Framework']
}
db.evenements.insert(conference_atoum)
--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
---
$evenements->insert(
array('type'=>'Conférence',
'titre'=>'Atoum, le framework de tests unitaires simple, ...',
'date'=>strtotime('2011-11-24 15:45:00'),
'minutes'=>45,
'tags'=>array('Industrialisation', 'Tests Unitaires', 'Framework'))
);
Requêtes types sur tableaux
> db.evenements.distinct('tags')
[ "Framework", "Industrialisation", "Tests Unitaires", "Experience",
"XML", "XQuery", "Optimisation", "XHRProf", "Marketing", "Asynchrone",
"Mongrel2", "ZeroMQ", "Cloud", "CMS", "REST", "Drupal", "Varnish",
"Optimisation,XDebug", "Securité", "", "Documentation", "VoiP",
"Outils" ]
> db.evenements.find({tags : {$in : ['Optimisation']}}).count()
8
> db.evenements.find({tags : {$all : ['Optimisation', 'Varnish']}}).
count()
1
> db.evenements.find({tags : {$nin : ['Optimisation']}, type :
'Conférences'}).count()
23
> db.evenements.find({tags : {$size : 0}})
...
Les opérateurs de
modification sur tableaux
● $push
● $pushAll
● $addToSet
● $pop
● $pull
● $pullAll
Requêtes type sur tableaux
> db.evenements.update({tags : {$in : [""]}}, {$pull : {tags : ""}})
> db.evenements.update({tags : {$in : ["Optimisation,XDebug"]}},
{$pushAll : {tags : ["Optimisation", "XDebug"]},
$pull : {tags : "Optimisation,XDebug"}})
---> Field name duplication not allowed with modifiers
> db.evenements.update({tags : {$in : ["Optimisation,XDebug"]}},
{$pushAll : {tags : ["Optimisation", "XDebug"]}})
> db.evenements.update({tags : {$in : ["Optimisation,XDebug"]}},
{$pull : {tags : "Optimisation,XDebug"}})
Requêtes type sur tableaux -
PHP
$evenements->update(
array('tags'=>array('$in'=>array('Optimisation,XDebug'))),
array('$pushAll'=>array('tags'=>array('Optimisation', 'XDebug')))
);
$evenements->update(
array('tags'=>array('$in'=>array('Optimisation,XDebug'))),
array('$pull'=>array('tags'=>'Optimisation,XDebug'))
);
$evenements->update(
array('tags'=>array('$in'=>array(""))),
array('$pull'=>array('tags'=>""))
);
Map / Reduce
result = db.runCommand({
... "mapreduce" : "evenements",
... "map" : map,
... "reduce" : reduce,
... "out" : {inline : 1}})
map = function() {
if (!this.tags) {
return;
}
for (index in this.tags) {
emit(this.tags[index], 1);
}
}
reduce = function(previous, current) {
var count = 0;
for (index in current) {
count += current[index];
}
return count;
}
{
"results" : [ {"_id" : "Asynchrone", "value" : 1},
{"_id" : "Experience","value" : 5},
{"_id" : "Framework","value" : 5},
{"_id" : "Industrialisation","value" : 7},
{"_id" : "Optimisation","value" : 10},
{"_id" : "Outils","value" : 1},
{"_id" : "Tests Unitaires","value" : 3},
{"_id" : "Varnish","value" : 1},
{"_id" : "VoiP","value" : 1},
{"_id" : "XDebug","value" : 2},
{"_id" : "XHRProf","value" : 1},
{"_id" : "XML","value" : 1},
{"_id" : "XQuery","value" : 1},
{"_id" : "ZeroMQ","value" : 1}
],
"timeMillis" : 64,
"counts" : {"input" : 36,"emit" : 48,"reduce" : 6,"
output" : 22},
"ok" : 1
}
Références
● L'équivalent de la clef étrangère
● MongoID / MongoDBRef
Requêtes type sur références
> geraldcroes = {nom : 'Croes', 'prenom' : 'Gerald', entreprise : 'Alptis'}
> db.conferenciers.save(geraldcroes)
> geraldcroes
{
"nom" : "Croes",
"prenom" : "Gerald",
"entreprise" : "Alptis",
"_id" : ObjectId("4ec933769f028924de1fb0df")
}
> conference_gerald = db.evenements.findOne({titre : 'hello $Mongo;'})
> conference_gerald.conferenciers = [new DBRef('conferenciers',
geraldcroes._id)]
> db.evenements.save(conference_gerald)
> db.evenements.find({conferenciers : {$in : [new DBRef('conferenciers',
geraldcroes._id)]}})
Requêtes type sur références
- PHP
$cd = array('prenom'=>'Cedric', 'nom'=>'Derue', 'entreprise'=>'Alptis');
$conferenciers->save($cd);
$conferenceMongo = $evenements->findOne(array('titre'=>'hello $Mongo;'));
$conferenceMongo['conferenciers'][] = $conferenciers->createDBRef($cd);
$evenements->save($conferenceMongo);
$evenements->findOne(
array('conferenciers'=>array(
'$in'=>array($conferenciers->createDBRef($cd))))
)
);
$evenements->find(array('conferenciers'=>array('$size'=>2)))
Documents embarqués
● Un niveau d'arborescence en plus
Requêtes type sur documents
embarqués
> conferencemongo = db.evenements.findOne({titre : 'hello $Mongo;'})
> conferencemongo.plan =
... [
... {titre : 'Introduction', slides : [1,2,3,4]},
... {titre : 'Persistance des donnees', slides : [5,6,7]}
... ]
> db.evenements.save(conferencemongo)
//Quelle conférence dispose d'une partie intitulée introduction ?
> db.evenements.find({'plan.titre' : 'Introduction'})
...
> db.evenements.distinct('plan.titre')
['Introduction', 'Persistance des donnees']
Requêtes type sur documents
embarqués - PHP
$plan = array(
array('titre'=>'Introduction', 'slides'=>array(1,2,3,4)),
array('titre'=>'Persistance des données', 'slides'=>array(5,6,7)),
array('titre'=>'Premier document', 'slides'=>array(8,9))
);
$conferenceMongo = $evenements->findOne(array('titre'=>'hello $Mongo;'));
$conferenceMongo['plan'] = $plan;
$evenements->save($conferenceMongo);
GridFS - Stockage de fichiers
● 2 collections spéciales : files et chuncks
Ajout / Lecture de fichiers
//Ecriture d'un fichier
$grid = $ct->phptour->getGridFS();
$id = $grid->storeFile("conferences.csv", array('meta1'=>'Superbe',
'meta2'=>'Vraiment superbe'));
//Lecture du fichier
$conferences = $grid->findOne(array('_id'=>$id));
echo $conferences->getBytes();
Intégration dans une application PHP
Frameworks MVC
● Zend Framework 1 et 2
● Symfony
● CakePHP
● Lithium
CMS
● Joomla
● Drupal
Diagramme de classes
Classes avec Doctrine ODM (1/7)
namespace PHPTour;
/** @Document */
class Conferencier
{
/** @Id */
private $id;
/** @String */
private $nom;
/** @String */
private $prenom;
/** @String */
private $entreprise;
}
Classes avec Doctrine ODM (2/7)
namespace PHPTour;
/**
* @Document
* @InheritanceType("SINGLE_COLLECTION")
* @DiscriminatorField(fieldName="type")
* @DiscriminatorMap({"PHPTourConference"="Conference","PHPTourPause"="
Pause"})
*/
abstract class Evenement
{
/** @Id */
protected $id;
/** @String */
protected $titre;
/** @Date */
protected $date;
/** @Int */
protected $minutes;
}
Classes avec Doctrine ODM (3/7)
namespace PHPTour;
/**
* @Document
*/
abstract class Presentation extends Evenement
{
/** @String */
protected $lieu;
/** @ReferenceMany(targetDocument="Conferencier")*/
protected $conferenciers;
}
Classes avec Doctrine ODM (4/7)
namespace PHPTour;
/** @Document */
class Pause extends Evenement
{
}
/**
* @Document
*/
class Keynote extends Presentation
{
}
Classes avec Doctrine ODM (5/7)
namespace PHPTour;
/** @Document */
class Slides
{
/** @Id */
private $_id;
/** @File */
private $_fichier;
/** @Field */
private $uploadDate;
/** @Field */
private $length;
/** @Field */
private $filename;
/** @Field */
private $md5;
}
Classes avec Doctrine ODM (6/7)
namespace PHPTour;
/**
* @EmbeddedDocument
*/
class ElementDePlan
{
/**
* @String
*/
protected $titre;
/**
* @Collection
*/
protected $slides;
}
Classes avec Doctrine ODM (7/7)
namespace PHPTour;
/**
* @Document
*/
class Conference extends Presentation
{
/** @Collection */
private $tags;
/** @EmbedMany */
protected $plan;
/**@ReferenceOne(targetDocument="Slides") */
protected $slides;
}
XML / YAML
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mongo-mapping ...>
<document name="PHPTourConferencier">
<field fieldName="id" id="true" />
<field fieldName="nom" type="string" />
<field fieldName="prenom" type="string" />
<field fieldName="entreprise" type="string" />
</document>
</doctrine-mongo-mapping>
PHPTourConferencier:
fields:
id:
type: id
id: true
nom:
type: string
prenom:
type: string
entreprise:
type: string
DocumentManager : initialisation
$config = new DoctrineODMMongoDBConfiguration();
$config->setProxyDir('path/to/geearate/proxies');
$config->setProxyNamespace('Proxies');
$config->setHydratorDir('path/to/generate/hydrators');
$config->setHydratorNamespace('Hydrators');
$reader = new DoctrineCommonAnnotationsAnnotationReader();
$reader->setDefaultAnnotationNamespace('DoctrineODMMongoDBMapping');
$config->setMetadataDriverImpl(new AnnotationDriver($reader));
$dm = DoctrineODMMongoDB
DocumentManager::create(new Mongo(), $config); (), $config);
DocumentManager
● Accès central de la persistance des données
● Implemente le pattern Unif Of Work
● Gestion de l'état des objets en mémoire (NEW,
MANAGED, DETACHED ou REMOVED)
Requêtes avec Doctrine
// SELECT ALL
$conferences = $dm->getRepository('PHPTourConference')->findBy(array());
// SELECT BY ID
$conference = $dm->find(' PHPTourConference', $id);
// SELECT BY CRITERIA
$conference = $dm->getRepository('PHPTourConference')
->findOneBy(array('titre' => 'Hello $Mongo'));
// INSERT OR UPDATE
$dm->persist($conference);
// DELETE
$dm->remove($conference);
GridFS
$conference = $dm->createQueryBuilder
('PHPTourConference')
->field('titre')
->equals('hello $Mongo;')
->getQuery()
->execute()
->getSingleResult();
header('Content-type: application/pdf');
echo $conference->getSlides()->getFichier()->getBytes();
Performances - Indexes
bd.Collection.ensureIndex({monChamp : 1})
bd.Collection.dropIndex()
bd.Collection.dropIndex({monChamp : 1})
● Opération coûteuse et bloquante
● Peut être réalisée en tâche de fond
db.Collection.ensureIndex({monChamp : 1},
{background : 1})
Performances - Indexes (2)
● Index sur plusieurs champs
db.ensureIndex({nom : 1, prenom : 1});
● Assurer l'unicité
db.ensureIndex({nom : 1, prenom : 1},
{unique : 1});
Performances - Indexes (3)
Pas toujours efficaces
● négations ($ne, $not, ...)
● Opérations arythmétiques ($mod, ...)
● Map / Reduce (boite noire pour l'optimiseur)
● La plupart des expressions rationelles (/a/)
Outils dev. et admin.
● RockMongo
● Fang of Mongo
● MongoExplorer (silverlight)
● MongoHub
● PHPMoAdmin
● Meclipse
● MongoVue
Questions ?
https://github.com/geraldcroes/MongoConference/
Photographies
Hangin by a thread - http://www.500px.com/photo/3159488 - Scott Smora
Pacific coast rail line - http://www.500px.com/photo/1739071 - Lachlan
Crossroads - http://500px.com/photo/206202 - DMitry Kot
Old book - http://500px.com/photo/841759 - Amar Chauhan
Inappropriately Dressed - White dress fast bike - http://500px.com/photo/330960 - Apollinaria Toloraya
junction - http://500px.com/photo/3113517 - Kai Ziehl
the cube - http://500px.com/photo/1365861 - Stephen L.
Sans titre - http://500px.com/photo/1125283 - James Tatum
What's in the box?- http://500px.com/photo/1292897 - Andrew Do
gears of war - http://500px.com/photo/672778 - Dave Kane
Link - http://500px.com/photo/514318 - Djura Stankovic Photography
Russian dolls lined up - http://www.flickr.com/photos/sunnyuk/3240916291/ - sunnyUK
records - http://500px.com/photo/1084138 - Jackson Carson
microphone - http://www.500px.com/photo/1910034 - Tchon T

Contenu connexe

Tendances

Procédures CLR pour SQL Server : avantages et inconvénients
Procédures CLR pour SQL Server : avantages et inconvénientsProcédures CLR pour SQL Server : avantages et inconvénients
Procédures CLR pour SQL Server : avantages et inconvénientsDenis Voituron
 
Introduction à JavaScript
Introduction à JavaScriptIntroduction à JavaScript
Introduction à JavaScriptAbdoulaye Dieng
 
Php 2 - Approfondissement MySQL, PDO et MVC
Php 2 - Approfondissement MySQL, PDO et MVCPhp 2 - Approfondissement MySQL, PDO et MVC
Php 2 - Approfondissement MySQL, PDO et MVCPierre Faure
 
Requêtes HTTP synchrones et asynchrones
Requêtes HTTPsynchrones et asynchronesRequêtes HTTPsynchrones et asynchrones
Requêtes HTTP synchrones et asynchronesAbdoulaye Dieng
 
Php mysql cours
Php mysql coursPhp mysql cours
Php mysql courszan
 
Programmation orientée objet en PHP 5
Programmation orientée objet en PHP 5Programmation orientée objet en PHP 5
Programmation orientée objet en PHP 5Kristen Le Liboux
 
Les nouveautés de java 7 et les promesses
Les nouveautés de java 7  et les promessesLes nouveautés de java 7  et les promesses
Les nouveautés de java 7 et les promessesEric Toguem
 
Cours php & Mysql - 2éme partie
Cours php & Mysql - 2éme partieCours php & Mysql - 2éme partie
Cours php & Mysql - 2éme partiekadzaki
 
Trouvez la faille! - Confoo 2012
Trouvez la faille! - Confoo 2012Trouvez la faille! - Confoo 2012
Trouvez la faille! - Confoo 2012Antonio Fontes
 
Notions de base de JavaScript
Notions de base de JavaScriptNotions de base de JavaScript
Notions de base de JavaScriptKristen Le Liboux
 

Tendances (14)

Procédures CLR pour SQL Server : avantages et inconvénients
Procédures CLR pour SQL Server : avantages et inconvénientsProcédures CLR pour SQL Server : avantages et inconvénients
Procédures CLR pour SQL Server : avantages et inconvénients
 
Mongodb102
Mongodb102Mongodb102
Mongodb102
 
Introduction à JavaScript
Introduction à JavaScriptIntroduction à JavaScript
Introduction à JavaScript
 
Php 2 - Approfondissement MySQL, PDO et MVC
Php 2 - Approfondissement MySQL, PDO et MVCPhp 2 - Approfondissement MySQL, PDO et MVC
Php 2 - Approfondissement MySQL, PDO et MVC
 
Requêtes HTTP synchrones et asynchrones
Requêtes HTTPsynchrones et asynchronesRequêtes HTTPsynchrones et asynchrones
Requêtes HTTP synchrones et asynchrones
 
Php mysql cours
Php mysql coursPhp mysql cours
Php mysql cours
 
Ruby STAR
Ruby STARRuby STAR
Ruby STAR
 
Programmation orientée objet en PHP 5
Programmation orientée objet en PHP 5Programmation orientée objet en PHP 5
Programmation orientée objet en PHP 5
 
Les nouveautés de java 7 et les promesses
Les nouveautés de java 7  et les promessesLes nouveautés de java 7  et les promesses
Les nouveautés de java 7 et les promesses
 
Cours php & Mysql - 2éme partie
Cours php & Mysql - 2éme partieCours php & Mysql - 2éme partie
Cours php & Mysql - 2éme partie
 
Trouvez la faille! - Confoo 2012
Trouvez la faille! - Confoo 2012Trouvez la faille! - Confoo 2012
Trouvez la faille! - Confoo 2012
 
Introduction à React
Introduction à ReactIntroduction à React
Introduction à React
 
Une Introduction à R
Une Introduction à RUne Introduction à R
Une Introduction à R
 
Notions de base de JavaScript
Notions de base de JavaScriptNotions de base de JavaScript
Notions de base de JavaScript
 

En vedette

Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Kris Wallsmith
 
Symfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODMSymfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODMJonathan Wage
 
Symfony with angular.pptx
Symfony with angular.pptxSymfony with angular.pptx
Symfony with angular.pptxEsokia
 
Xarxes Socials X S G F
Xarxes  Socials  X S G FXarxes  Socials  X S G F
Xarxes Socials X S G FGuifre
 
virus informatico
virus informaticovirus informatico
virus informaticomiguelero20
 
Alimentation
AlimentationAlimentation
Alimentationlitous
 
La Vida De Les Estrelles
La Vida De Les EstrellesLa Vida De Les Estrelles
La Vida De Les EstrellesJoan xxiii
 
Dossier modelo argentino
Dossier modelo argentinoDossier modelo argentino
Dossier modelo argentinojuankrlosv
 
Ensayo jornada colosio
Ensayo jornada colosioEnsayo jornada colosio
Ensayo jornada colosiocebecinj
 
Créer sa micro entreprise light itsal ng
Créer sa micro entreprise light  itsal   ngCréer sa micro entreprise light  itsal   ng
Créer sa micro entreprise light itsal ngKBNTIC
 
New void book_i_phone
New void book_i_phoneNew void book_i_phone
New void book_i_phoneKhalid Ahmada
 
Shs fr4 oat and wat 2 practice
Shs fr4 oat and wat 2 practiceShs fr4 oat and wat 2 practice
Shs fr4 oat and wat 2 practiceDoug Doug
 
Diapositiva de ejemplo slideshare piura
Diapositiva de ejemplo slideshare piuraDiapositiva de ejemplo slideshare piura
Diapositiva de ejemplo slideshare piuraccynieto
 
Présentation des logiciels libres LINAGORA
Présentation des logiciels libres LINAGORAPrésentation des logiciels libres LINAGORA
Présentation des logiciels libres LINAGORALinuQ
 

En vedette (20)

Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)Doctrine MongoDB ODM (PDXPHP)
Doctrine MongoDB ODM (PDXPHP)
 
Symfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODMSymfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODM
 
Symfony Best Practices
Symfony Best PracticesSymfony Best Practices
Symfony Best Practices
 
Symfony with angular.pptx
Symfony with angular.pptxSymfony with angular.pptx
Symfony with angular.pptx
 
Xarxes Socials X S G F
Xarxes  Socials  X S G FXarxes  Socials  X S G F
Xarxes Socials X S G F
 
virus informatico
virus informaticovirus informatico
virus informatico
 
Design patterns
Design patternsDesign patterns
Design patterns
 
Alimentation
AlimentationAlimentation
Alimentation
 
La Vida De Les Estrelles
La Vida De Les EstrellesLa Vida De Les Estrelles
La Vida De Les Estrelles
 
Censo 2010
Censo 2010Censo 2010
Censo 2010
 
Nature
NatureNature
Nature
 
Dossier modelo argentino
Dossier modelo argentinoDossier modelo argentino
Dossier modelo argentino
 
Ensayo jornada colosio
Ensayo jornada colosioEnsayo jornada colosio
Ensayo jornada colosio
 
Créer sa micro entreprise light itsal ng
Créer sa micro entreprise light  itsal   ngCréer sa micro entreprise light  itsal   ng
Créer sa micro entreprise light itsal ng
 
New void book_i_phone
New void book_i_phoneNew void book_i_phone
New void book_i_phone
 
Shs fr4 oat and wat 2 practice
Shs fr4 oat and wat 2 practiceShs fr4 oat and wat 2 practice
Shs fr4 oat and wat 2 practice
 
Diapositiva de ejemplo slideshare piura
Diapositiva de ejemplo slideshare piuraDiapositiva de ejemplo slideshare piura
Diapositiva de ejemplo slideshare piura
 
Nueva gramatica
Nueva gramaticaNueva gramatica
Nueva gramatica
 
Gingerbread sur x8
Gingerbread sur x8Gingerbread sur x8
Gingerbread sur x8
 
Présentation des logiciels libres LINAGORA
Présentation des logiciels libres LINAGORAPrésentation des logiciels libres LINAGORA
Présentation des logiciels libres LINAGORA
 

Similaire à Hello mongo

Nosql, hadoop, map reduce, hbase, sqoop, voldemort, cassandra -intro
Nosql, hadoop, map reduce, hbase, sqoop, voldemort, cassandra -introNosql, hadoop, map reduce, hbase, sqoop, voldemort, cassandra -intro
Nosql, hadoop, map reduce, hbase, sqoop, voldemort, cassandra -introOlivier Mallassi
 
Tout ce que le getting started mongo db ne vous dira pas
Tout ce que le getting started mongo db ne vous dira pasTout ce que le getting started mongo db ne vous dira pas
Tout ce que le getting started mongo db ne vous dira pasPierre-Alban DEWITTE
 
Tout ce que le getting started MongoDB ne vous dira pas
Tout ce que le getting started MongoDB ne vous dira pasTout ce que le getting started MongoDB ne vous dira pas
Tout ce que le getting started MongoDB ne vous dira pasBruno Bonnin
 
Découverte du moteur de rendu du projet Spartan
Découverte du moteur de rendu du projet SpartanDécouverte du moteur de rendu du projet Spartan
Découverte du moteur de rendu du projet SpartanMicrosoft
 
Importer des données dans Nuxeo Platform - Nuxeo Tour 2014 - workshop
Importer des données dans Nuxeo Platform - Nuxeo Tour 2014 - workshopImporter des données dans Nuxeo Platform - Nuxeo Tour 2014 - workshop
Importer des données dans Nuxeo Platform - Nuxeo Tour 2014 - workshopNuxeo
 
SSL 2011 : Présentation de 2 bases noSQL
SSL 2011 : Présentation de 2 bases noSQLSSL 2011 : Présentation de 2 bases noSQL
SSL 2011 : Présentation de 2 bases noSQLHervé Leclerc
 
Symfony2 - Un Framework PHP 5 Performant
Symfony2 - Un Framework PHP 5 PerformantSymfony2 - Un Framework PHP 5 Performant
Symfony2 - Un Framework PHP 5 PerformantHugo Hamon
 
2014 03-26-appdevseries-session3-interactingwiththedatabase-fr-phpapp01-rev.
2014 03-26-appdevseries-session3-interactingwiththedatabase-fr-phpapp01-rev.2014 03-26-appdevseries-session3-interactingwiththedatabase-fr-phpapp01-rev.
2014 03-26-appdevseries-session3-interactingwiththedatabase-fr-phpapp01-rev.MongoDB
 
Tout ce que le getting started mongodb ne vous dira pas
Tout ce que le getting started mongodb ne vous dira pasTout ce que le getting started mongodb ne vous dira pas
Tout ce que le getting started mongodb ne vous dira pasBruno Bonnin
 
[JDLL 2018] Templer, Git, Bootstrap, PHP : des outils libres pour concevoir l...
[JDLL 2018] Templer, Git, Bootstrap, PHP : des outils libres pour concevoir l...[JDLL 2018] Templer, Git, Bootstrap, PHP : des outils libres pour concevoir l...
[JDLL 2018] Templer, Git, Bootstrap, PHP : des outils libres pour concevoir l...Clément OUDOT
 
Réussir une montée en charge avec MongoDB
Réussir une montée en charge avec MongoDBRéussir une montée en charge avec MongoDB
Réussir une montée en charge avec MongoDB MongoDB
 
Open close principle, on a dit étendre, pas extends !
Open close principle, on a dit étendre, pas extends !Open close principle, on a dit étendre, pas extends !
Open close principle, on a dit étendre, pas extends !Engineor
 
Enib cours c.a.i. web - séance #1 - html5 css3-js - 2
Enib   cours c.a.i. web - séance #1 - html5 css3-js - 2Enib   cours c.a.i. web - séance #1 - html5 css3-js - 2
Enib cours c.a.i. web - séance #1 - html5 css3-js - 2Horacio Gonzalez
 

Similaire à Hello mongo (20)

Nosql, hadoop, map reduce, hbase, sqoop, voldemort, cassandra -intro
Nosql, hadoop, map reduce, hbase, sqoop, voldemort, cassandra -introNosql, hadoop, map reduce, hbase, sqoop, voldemort, cassandra -intro
Nosql, hadoop, map reduce, hbase, sqoop, voldemort, cassandra -intro
 
Tout ce que le getting started mongo db ne vous dira pas
Tout ce que le getting started mongo db ne vous dira pasTout ce que le getting started mongo db ne vous dira pas
Tout ce que le getting started mongo db ne vous dira pas
 
Tout ce que le getting started MongoDB ne vous dira pas
Tout ce que le getting started MongoDB ne vous dira pasTout ce que le getting started MongoDB ne vous dira pas
Tout ce que le getting started MongoDB ne vous dira pas
 
Découverte du moteur de rendu du projet Spartan
Découverte du moteur de rendu du projet SpartanDécouverte du moteur de rendu du projet Spartan
Découverte du moteur de rendu du projet Spartan
 
Importer des données dans Nuxeo Platform - Nuxeo Tour 2014 - workshop
Importer des données dans Nuxeo Platform - Nuxeo Tour 2014 - workshopImporter des données dans Nuxeo Platform - Nuxeo Tour 2014 - workshop
Importer des données dans Nuxeo Platform - Nuxeo Tour 2014 - workshop
 
Introduction à node.js
Introduction à node.js Introduction à node.js
Introduction à node.js
 
Algo poo ts
Algo poo tsAlgo poo ts
Algo poo ts
 
Pytong2015
Pytong2015Pytong2015
Pytong2015
 
SSL 2011 : Présentation de 2 bases noSQL
SSL 2011 : Présentation de 2 bases noSQLSSL 2011 : Présentation de 2 bases noSQL
SSL 2011 : Présentation de 2 bases noSQL
 
HTML5 en projet
HTML5 en projetHTML5 en projet
HTML5 en projet
 
Symfony2 - Un Framework PHP 5 Performant
Symfony2 - Un Framework PHP 5 PerformantSymfony2 - Un Framework PHP 5 Performant
Symfony2 - Un Framework PHP 5 Performant
 
2014 03-26-appdevseries-session3-interactingwiththedatabase-fr-phpapp01-rev.
2014 03-26-appdevseries-session3-interactingwiththedatabase-fr-phpapp01-rev.2014 03-26-appdevseries-session3-interactingwiththedatabase-fr-phpapp01-rev.
2014 03-26-appdevseries-session3-interactingwiththedatabase-fr-phpapp01-rev.
 
Tout ce que le getting started mongodb ne vous dira pas
Tout ce que le getting started mongodb ne vous dira pasTout ce que le getting started mongodb ne vous dira pas
Tout ce que le getting started mongodb ne vous dira pas
 
[JDLL 2018] Templer, Git, Bootstrap, PHP : des outils libres pour concevoir l...
[JDLL 2018] Templer, Git, Bootstrap, PHP : des outils libres pour concevoir l...[JDLL 2018] Templer, Git, Bootstrap, PHP : des outils libres pour concevoir l...
[JDLL 2018] Templer, Git, Bootstrap, PHP : des outils libres pour concevoir l...
 
Réussir une montée en charge avec MongoDB
Réussir une montée en charge avec MongoDBRéussir une montée en charge avec MongoDB
Réussir une montée en charge avec MongoDB
 
Open close principle, on a dit étendre, pas extends !
Open close principle, on a dit étendre, pas extends !Open close principle, on a dit étendre, pas extends !
Open close principle, on a dit étendre, pas extends !
 
Enib cours c.a.i. web - séance #1 - html5 css3-js - 2
Enib   cours c.a.i. web - séance #1 - html5 css3-js - 2Enib   cours c.a.i. web - séance #1 - html5 css3-js - 2
Enib cours c.a.i. web - séance #1 - html5 css3-js - 2
 
Mongo DB
Mongo DBMongo DB
Mongo DB
 
Drools et les moteurs de règles
Drools et les moteurs de règlesDrools et les moteurs de règles
Drools et les moteurs de règles
 
iTunes Stats
iTunes StatsiTunes Stats
iTunes Stats
 

Plus de CEDRIC DERUE

Créer des applications intelligentes avec la recherche vectorielle dans Azure...
Créer des applications intelligentes avec la recherche vectorielle dans Azure...Créer des applications intelligentes avec la recherche vectorielle dans Azure...
Créer des applications intelligentes avec la recherche vectorielle dans Azure...CEDRIC DERUE
 
waypoint-with-github-for-a-paas-experience.pdf
waypoint-with-github-for-a-paas-experience.pdfwaypoint-with-github-for-a-paas-experience.pdf
waypoint-with-github-for-a-paas-experience.pdfCEDRIC DERUE
 
Building and deploying microservices to Azure with GitHub and Waypoint
Building and deploying microservices to Azure with GitHub and Waypoint Building and deploying microservices to Azure with GitHub and Waypoint
Building and deploying microservices to Azure with GitHub and Waypoint CEDRIC DERUE
 
Patterns du continuous delivery avec azure dev ops et kubernetes
Patterns du continuous delivery avec azure dev ops et kubernetesPatterns du continuous delivery avec azure dev ops et kubernetes
Patterns du continuous delivery avec azure dev ops et kubernetesCEDRIC DERUE
 
How to deploy Zend Expressive microservices to Microsoft Azure
How to deploy Zend Expressive microservices to Microsoft AzureHow to deploy Zend Expressive microservices to Microsoft Azure
How to deploy Zend Expressive microservices to Microsoft AzureCEDRIC DERUE
 
From Zero to Hero : construire des applications PHP scalables avec Zend Serve...
From Zero to Hero : construire des applications PHP scalables avec Zend Serve...From Zero to Hero : construire des applications PHP scalables avec Zend Serve...
From Zero to Hero : construire des applications PHP scalables avec Zend Serve...CEDRIC DERUE
 
Microsoft TechDays Tour 2015 - Approche DevOps Open Source pour les applicati...
Microsoft TechDays Tour 2015 - Approche DevOps Open Source pour les applicati...Microsoft TechDays Tour 2015 - Approche DevOps Open Source pour les applicati...
Microsoft TechDays Tour 2015 - Approche DevOps Open Source pour les applicati...CEDRIC DERUE
 
Approche DevOps pour builder une solution robuste PHP avec Zend_Server et Azure
Approche DevOps pour builder une solution robuste PHP avec Zend_Server et AzureApproche DevOps pour builder une solution robuste PHP avec Zend_Server et Azure
Approche DevOps pour builder une solution robuste PHP avec Zend_Server et AzureCEDRIC DERUE
 
Rhinos have tea_on_azure
Rhinos have tea_on_azureRhinos have tea_on_azure
Rhinos have tea_on_azureCEDRIC DERUE
 
Playing with php_on_azure
Playing with php_on_azurePlaying with php_on_azure
Playing with php_on_azureCEDRIC DERUE
 

Plus de CEDRIC DERUE (10)

Créer des applications intelligentes avec la recherche vectorielle dans Azure...
Créer des applications intelligentes avec la recherche vectorielle dans Azure...Créer des applications intelligentes avec la recherche vectorielle dans Azure...
Créer des applications intelligentes avec la recherche vectorielle dans Azure...
 
waypoint-with-github-for-a-paas-experience.pdf
waypoint-with-github-for-a-paas-experience.pdfwaypoint-with-github-for-a-paas-experience.pdf
waypoint-with-github-for-a-paas-experience.pdf
 
Building and deploying microservices to Azure with GitHub and Waypoint
Building and deploying microservices to Azure with GitHub and Waypoint Building and deploying microservices to Azure with GitHub and Waypoint
Building and deploying microservices to Azure with GitHub and Waypoint
 
Patterns du continuous delivery avec azure dev ops et kubernetes
Patterns du continuous delivery avec azure dev ops et kubernetesPatterns du continuous delivery avec azure dev ops et kubernetes
Patterns du continuous delivery avec azure dev ops et kubernetes
 
How to deploy Zend Expressive microservices to Microsoft Azure
How to deploy Zend Expressive microservices to Microsoft AzureHow to deploy Zend Expressive microservices to Microsoft Azure
How to deploy Zend Expressive microservices to Microsoft Azure
 
From Zero to Hero : construire des applications PHP scalables avec Zend Serve...
From Zero to Hero : construire des applications PHP scalables avec Zend Serve...From Zero to Hero : construire des applications PHP scalables avec Zend Serve...
From Zero to Hero : construire des applications PHP scalables avec Zend Serve...
 
Microsoft TechDays Tour 2015 - Approche DevOps Open Source pour les applicati...
Microsoft TechDays Tour 2015 - Approche DevOps Open Source pour les applicati...Microsoft TechDays Tour 2015 - Approche DevOps Open Source pour les applicati...
Microsoft TechDays Tour 2015 - Approche DevOps Open Source pour les applicati...
 
Approche DevOps pour builder une solution robuste PHP avec Zend_Server et Azure
Approche DevOps pour builder une solution robuste PHP avec Zend_Server et AzureApproche DevOps pour builder une solution robuste PHP avec Zend_Server et Azure
Approche DevOps pour builder une solution robuste PHP avec Zend_Server et Azure
 
Rhinos have tea_on_azure
Rhinos have tea_on_azureRhinos have tea_on_azure
Rhinos have tea_on_azure
 
Playing with php_on_azure
Playing with php_on_azurePlaying with php_on_azure
Playing with php_on_azure
 

Hello mongo

  • 1. hello $Mongo Introduction à MongoDB Gérald Croës http://croes.org/gerald/blog/ @geraldcroes Cédric Derue @cderue http://www.croes.org/gerald/conf/php/lille/2011/helloMongo.pdf
  • 2. Il est encore temps de quitter la salle... ● Pas de schéma ● Non transactionnel ● Pas de jointures ● Pas de contrainte d'intégrité ● Pas de SQL ● Peu d'intégration avec des outils d'entreprise ● Limité à 2Go <- Version 32bits
  • 3. ... ou alors de rester ● Facilité ● Rapidité ● Scalabilité ● Pas de limitation (64bits) ● Disponible sur la plupart des plateformes
  • 4. Plan ● Intro : Persistance des données ● Partie 1 : Développement d'une application de gestion de conférence ● Partie 2 : Mongo & ODM (Doctrine) ● Partie 3 : Index
  • 7. Pourquoi une base de données ? ● Lecture ● Ecriture ● Concurrence d'accès ● Recherche efficace ● Interopérabilité
  • 8. La réponse MongoDB ● Lecture / Ecriture des données très rapide ● Base de données orientée Document ● Format JSON / BSON ● Scalabilité horizontale
  • 9. Le cas du blog relationnel... Utilisateur ------------------- Nom Prénom Blog ---------------------- Nom Commentaires ---------------------- Texte Date Articles ---------------------- Texte Date Tags ---------------------- Nom Utilisateur_Articles -------------------------- id id
  • 10. Le cas du blog {Documents} Utilisateur ------------------- Nom Prénom Blog ---------------------- Nom Articles ---------------------- Texte Date Commentaires ---------------------- Texte Date Tags ---------------------- Nom Cohésion avec le modèle Objet
  • 11. Petit lexique non illustré Relationnel MongoDB Base de données Base de données Table Collection Index Index Enregistrement Document Colonne Champ / Propriété Clé étrangère Référence Jointures Documents embarqués Clé primaire ObjectID ORM ODM
  • 12. Installation de MongoDB ● Téléchargement wget http://fastdl.mongodb.org/linux/ mongodb-linux-x86_64-2.0.1.tgz tar xzf mongodb.tgz ● Répertoire de données sudo mkdir -p /data/db sudo chown `id -u` /data/db ● Lancement mongodb/bin/mongod
  • 13. Installation du driver PHP pecl install mongo extension = mongo.so | php_mongo.dll
  • 14. Un premier document use phptour conference = { titre : "hello $Mongo;", lieu : "Salle de conférence 1" } db.evenements.save(conference)
  • 15. Un premier document - recherche db.evenements.find() { "_id" : ObjectId("xxxxxxxxxxx"), "titre" : "hello $Mongo;", "lieu" : "Salle de conférence 1" } Un identifiant _id généré automatiquement
  • 16. Qu'avons nous donc ? show dbs local (empty) phptour test (empty) show collections evenements system.indexes
  • 17. Premiers constats ● Bases de données dynamiques ● Collections dynamiques ● Enregistrements ajoutés sans contrainte ● JSON Pas de schéma préalable
  • 18. JSon ? JSON = JavaScript Object Notation { 'langage' : { 'nom' : 'json', 'points_forts' : ['lisible', 'souple', 'intégré', 'compact'] } } <?php echo json_encode( array( 'language'=>array( 'nom' => 'json', 'points_forts' => array( 'lisible', 'souple', 'intégré', 'compact' ) ) ) ); //json_decode
  • 19. BSon - Binary JSon ● Une surcouche de JSon ● Plus rapide à lire / écrire ○ Ecriture des entiers tels que ○ Informations supplémentaires de taille
  • 20. Retour au document - PHP //connection à la base de données $ct = new Mongo(); //Sélection de la base phptour $db = $ct->phptour; //Sélection de la collection conferences $evenements = $db->evenements; $conferenceMongo = array('titre' => 'hello $Mongo;', 'lieu' => 'Salle de conférence 1'); $evenements->insert($conferenceMongo);
  • 21. Les objets Mongo (1/2) ● Mongo ○ Connexion à la base ○ close(), connect(), listDBs(), selectDB(), selectCollection() ● MongoDB ○ Base de données ○ createCollection(), selectCollection(), createDBRef(), getDBRef(), drop(), getGridFS()
  • 22. Sélection des données - PHP //Sélection du contenu de la base foreach ($evenements->find() as $document) { echo "{$document['titre']} ({$document['_id']})nr"; } //Sélection d'un seul élément $document = $evenements ->findOne(array('_id'=>new MongoId ('xxxxx'))); //Sélection du seul titre de la conférence $document = $evenements ->findOne(array('_id'=>new MongoId('xxxxx')), array('titre'));
  • 23. Les objets Mongo (2/2) ● MongoCollection ○ Collection ○ count(), find(), findOne(), insert(), remove(), save(), update() ● MongoCursor ○ Curseur sur résultat de requête ○ getNext(), count(), hint(), limit(), skip(), sort()
  • 24. Modification du schéma //Remplacement de tout le document db.evenements.update( {titre : "hello $Mongo;"}, {titre : "hello $Mongo;", lieu : "Salle de conférence 1", date : ISODate('2011-11-24 10:15:00') } ) //Utilisation d'opérateurs db.evenements.update( {titre : "hello $Mongo;"}, {$set : {date : ISODate('2011-11-24 10:15:00')}} )
  • 25. Les opérateurs de modification ● $set - ajout d'une propriété ● $unset - suppression d'une propriété ● $inc - incrémenter la valeur d'une propriété numérique ● $rename - renommer une propriété
  • 26. Modification du schéma - PHP $ct = new Mongo(); $evenements = $ct->phptour->evenements; $evenements->update( array('titre'=>'hello $Mongo;'), array('titre'=>'hello $Mongo;', 'lieu'=>'Salle de conférence 1', 'date'=>new MongoDate(strtotime('2011-11-24 10: 15:00')))); //Utilisation d'opérateurs $evenements->update( array('titre'=>'hello $Mongo;'), array('$set'=>array('date'=>new MongoDate(strtotime ('2011-11-24 10:15:30')))) );
  • 27. Quelques données supplémentaires $keynote = array('titre' => "Keynote d'ouverture", 'lieu' => 'Auditorium', 'date'=>new MongoDate(strtotime('2011-11-24 9: 00:00')), 'type'=>'Keynote', 'minutes'=>30); $repas = array('titre' => "Repas", 'date'=>new MongoDate(strtotime('2011-11-24 12:45:00')), 'type'=>'Pause', 'minutes'=>60); $pauseMatin = array('titre' => "Pause", 'date'=>new MongoDate(strtotime('2011-11-24 11:00:00')), 'type'=>'Pause', 'minutes'=>15); $pauseAM = array('titre' => "Pause", 'date'=>new MongoDate(strtotime('2011-11-24 15:30:00')), 'type'=>'Pause', 'minutes'=>15); $evenements->insert($keynote); $evenements->insert($repas); $evenements->insert($pauseMatin); $evenements->insert($pauseAM);
  • 28. Deuxième constat Données qui n'ont pas la même structure ● type ● lieu ● minutes
  • 29. Requêtes type > db.evenements.distinct("type"); ["Keynote", "Pause"] > db.evenements.distinct("minutes", {type : "Pause"}) [60, 15] > db.evenements.find({type : "Pause"}).count() 3 > db.evenements.group({ ... key : { minutes : true}, ... cond : { type : "Pause" }, ... reduce : function (obj, prev) { prev.nb += 1; }, ... initial : {nb : 0} ... }); [ { "minutes" : 60, "nb" : 1 }, { "minutes" : 15, "nb" : 2 } ]
  • 30. Requêtes type - PHP $ct->phptour->command(array('distinct'=>'evenements', 'key'=>'type'); $ct->phptour->command(array('distinct'=>'evenements', 'key'=>'minutes', 'query'=>array('type' => 'Pause')); $evenements->find(array('type'=>'Pause'))->count(); $evenements->group( array('minutes'=>1), array('nb'=>0), 'function (obj, prev) { prev.nb += 1; }', array('type'=>'Pause') );
  • 31. Opérateurs de requête (1/2) $lt < $lte <= $gt > $gte >= > db.evenements.find({minutes : {$gte : 30}}) { "_id" : ObjectId("4ebf87db945630cc0a000000"), "titre" : "Keynote d'ouverture", "lieu" : "Auditorium", "date" : ISODate("2011-11-24T08:00: 00Z"), "type" : "Keynote", "minutes" : 30 } { "_id" : ObjectId("4ebf87db945630cc0a000001"), "titre" : "Repas", "date" : ISODate("2011-11-24T11:45:00Z"), "type" : "Pause", "minutes" : 60 }
  • 32. Opérateurs de requête (2/2) $exists $or $nor $and $mod $ne $in $nin $all
  • 33. Exemples opérateurs //PHP $evenements->update( array('type'=>array('$exists'=>false)), array('$set'=>array('type'=>'Conference', 'minutes'=>45)) ); //Mongo > db.evenements.find({minutes : {$in : [30, 15]}}) { "_id" : ObjectId("4ebf87db945630cc0a000000"), "titre" : "Keynote d'ouverture", "lieu" : "Auditorium", "date" : ISODate("2011-11-24T08:00: 00Z"), "type" : "Keynote", "minutes" : 30 } { "_id" : ObjectId("4ebf87db945630cc0a000002"), "titre" : "Pause", "date" : ISODate("2011-11-24T10:00:00Z"), "type" : "Pause", "minutes" : 15 } { "_id" : ObjectId("4ebf87db945630cc0a000003"), "titre" : "Pause", "date" : ISODate("2011-11-24T14:30:00Z"), "type" : "Pause", "minutes" : 15 }
  • 34. Propriétés multivaluées ● Nouvelle table ● Jointures ● Clefs étrangères ● Contraintes d'intégrité ● Modification des services
  • 35. Ajout de tags conference_atoum = { type : 'Conférence', titre : 'Atoum', date : ISODate('2011-11-24 15:45:00'), minutes : 45, tags : ['Industrialisation', 'Tests Unitaires', 'Framework'] } db.evenements.insert(conference_atoum) --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- $evenements->insert( array('type'=>'Conférence', 'titre'=>'Atoum, le framework de tests unitaires simple, ...', 'date'=>strtotime('2011-11-24 15:45:00'), 'minutes'=>45, 'tags'=>array('Industrialisation', 'Tests Unitaires', 'Framework')) );
  • 36. Requêtes types sur tableaux > db.evenements.distinct('tags') [ "Framework", "Industrialisation", "Tests Unitaires", "Experience", "XML", "XQuery", "Optimisation", "XHRProf", "Marketing", "Asynchrone", "Mongrel2", "ZeroMQ", "Cloud", "CMS", "REST", "Drupal", "Varnish", "Optimisation,XDebug", "Securité", "", "Documentation", "VoiP", "Outils" ] > db.evenements.find({tags : {$in : ['Optimisation']}}).count() 8 > db.evenements.find({tags : {$all : ['Optimisation', 'Varnish']}}). count() 1 > db.evenements.find({tags : {$nin : ['Optimisation']}, type : 'Conférences'}).count() 23 > db.evenements.find({tags : {$size : 0}}) ...
  • 37. Les opérateurs de modification sur tableaux ● $push ● $pushAll ● $addToSet ● $pop ● $pull ● $pullAll
  • 38. Requêtes type sur tableaux > db.evenements.update({tags : {$in : [""]}}, {$pull : {tags : ""}}) > db.evenements.update({tags : {$in : ["Optimisation,XDebug"]}}, {$pushAll : {tags : ["Optimisation", "XDebug"]}, $pull : {tags : "Optimisation,XDebug"}}) ---> Field name duplication not allowed with modifiers > db.evenements.update({tags : {$in : ["Optimisation,XDebug"]}}, {$pushAll : {tags : ["Optimisation", "XDebug"]}}) > db.evenements.update({tags : {$in : ["Optimisation,XDebug"]}}, {$pull : {tags : "Optimisation,XDebug"}})
  • 39. Requêtes type sur tableaux - PHP $evenements->update( array('tags'=>array('$in'=>array('Optimisation,XDebug'))), array('$pushAll'=>array('tags'=>array('Optimisation', 'XDebug'))) ); $evenements->update( array('tags'=>array('$in'=>array('Optimisation,XDebug'))), array('$pull'=>array('tags'=>'Optimisation,XDebug')) ); $evenements->update( array('tags'=>array('$in'=>array(""))), array('$pull'=>array('tags'=>"")) );
  • 40. Map / Reduce result = db.runCommand({ ... "mapreduce" : "evenements", ... "map" : map, ... "reduce" : reduce, ... "out" : {inline : 1}}) map = function() { if (!this.tags) { return; } for (index in this.tags) { emit(this.tags[index], 1); } } reduce = function(previous, current) { var count = 0; for (index in current) { count += current[index]; } return count; } { "results" : [ {"_id" : "Asynchrone", "value" : 1}, {"_id" : "Experience","value" : 5}, {"_id" : "Framework","value" : 5}, {"_id" : "Industrialisation","value" : 7}, {"_id" : "Optimisation","value" : 10}, {"_id" : "Outils","value" : 1}, {"_id" : "Tests Unitaires","value" : 3}, {"_id" : "Varnish","value" : 1}, {"_id" : "VoiP","value" : 1}, {"_id" : "XDebug","value" : 2}, {"_id" : "XHRProf","value" : 1}, {"_id" : "XML","value" : 1}, {"_id" : "XQuery","value" : 1}, {"_id" : "ZeroMQ","value" : 1} ], "timeMillis" : 64, "counts" : {"input" : 36,"emit" : 48,"reduce" : 6," output" : 22}, "ok" : 1 }
  • 41. Références ● L'équivalent de la clef étrangère ● MongoID / MongoDBRef
  • 42. Requêtes type sur références > geraldcroes = {nom : 'Croes', 'prenom' : 'Gerald', entreprise : 'Alptis'} > db.conferenciers.save(geraldcroes) > geraldcroes { "nom" : "Croes", "prenom" : "Gerald", "entreprise" : "Alptis", "_id" : ObjectId("4ec933769f028924de1fb0df") } > conference_gerald = db.evenements.findOne({titre : 'hello $Mongo;'}) > conference_gerald.conferenciers = [new DBRef('conferenciers', geraldcroes._id)] > db.evenements.save(conference_gerald) > db.evenements.find({conferenciers : {$in : [new DBRef('conferenciers', geraldcroes._id)]}})
  • 43. Requêtes type sur références - PHP $cd = array('prenom'=>'Cedric', 'nom'=>'Derue', 'entreprise'=>'Alptis'); $conferenciers->save($cd); $conferenceMongo = $evenements->findOne(array('titre'=>'hello $Mongo;')); $conferenceMongo['conferenciers'][] = $conferenciers->createDBRef($cd); $evenements->save($conferenceMongo); $evenements->findOne( array('conferenciers'=>array( '$in'=>array($conferenciers->createDBRef($cd)))) ) ); $evenements->find(array('conferenciers'=>array('$size'=>2)))
  • 44. Documents embarqués ● Un niveau d'arborescence en plus
  • 45. Requêtes type sur documents embarqués > conferencemongo = db.evenements.findOne({titre : 'hello $Mongo;'}) > conferencemongo.plan = ... [ ... {titre : 'Introduction', slides : [1,2,3,4]}, ... {titre : 'Persistance des donnees', slides : [5,6,7]} ... ] > db.evenements.save(conferencemongo) //Quelle conférence dispose d'une partie intitulée introduction ? > db.evenements.find({'plan.titre' : 'Introduction'}) ... > db.evenements.distinct('plan.titre') ['Introduction', 'Persistance des donnees']
  • 46. Requêtes type sur documents embarqués - PHP $plan = array( array('titre'=>'Introduction', 'slides'=>array(1,2,3,4)), array('titre'=>'Persistance des données', 'slides'=>array(5,6,7)), array('titre'=>'Premier document', 'slides'=>array(8,9)) ); $conferenceMongo = $evenements->findOne(array('titre'=>'hello $Mongo;')); $conferenceMongo['plan'] = $plan; $evenements->save($conferenceMongo);
  • 47. GridFS - Stockage de fichiers ● 2 collections spéciales : files et chuncks
  • 48. Ajout / Lecture de fichiers //Ecriture d'un fichier $grid = $ct->phptour->getGridFS(); $id = $grid->storeFile("conferences.csv", array('meta1'=>'Superbe', 'meta2'=>'Vraiment superbe')); //Lecture du fichier $conferences = $grid->findOne(array('_id'=>$id)); echo $conferences->getBytes();
  • 49. Intégration dans une application PHP Frameworks MVC ● Zend Framework 1 et 2 ● Symfony ● CakePHP ● Lithium CMS ● Joomla ● Drupal
  • 51. Classes avec Doctrine ODM (1/7) namespace PHPTour; /** @Document */ class Conferencier { /** @Id */ private $id; /** @String */ private $nom; /** @String */ private $prenom; /** @String */ private $entreprise; }
  • 52. Classes avec Doctrine ODM (2/7) namespace PHPTour; /** * @Document * @InheritanceType("SINGLE_COLLECTION") * @DiscriminatorField(fieldName="type") * @DiscriminatorMap({"PHPTourConference"="Conference","PHPTourPause"=" Pause"}) */ abstract class Evenement { /** @Id */ protected $id; /** @String */ protected $titre; /** @Date */ protected $date; /** @Int */ protected $minutes; }
  • 53. Classes avec Doctrine ODM (3/7) namespace PHPTour; /** * @Document */ abstract class Presentation extends Evenement { /** @String */ protected $lieu; /** @ReferenceMany(targetDocument="Conferencier")*/ protected $conferenciers; }
  • 54. Classes avec Doctrine ODM (4/7) namespace PHPTour; /** @Document */ class Pause extends Evenement { } /** * @Document */ class Keynote extends Presentation { }
  • 55. Classes avec Doctrine ODM (5/7) namespace PHPTour; /** @Document */ class Slides { /** @Id */ private $_id; /** @File */ private $_fichier; /** @Field */ private $uploadDate; /** @Field */ private $length; /** @Field */ private $filename; /** @Field */ private $md5; }
  • 56. Classes avec Doctrine ODM (6/7) namespace PHPTour; /** * @EmbeddedDocument */ class ElementDePlan { /** * @String */ protected $titre; /** * @Collection */ protected $slides; }
  • 57. Classes avec Doctrine ODM (7/7) namespace PHPTour; /** * @Document */ class Conference extends Presentation { /** @Collection */ private $tags; /** @EmbedMany */ protected $plan; /**@ReferenceOne(targetDocument="Slides") */ protected $slides; }
  • 58. XML / YAML <?xml version="1.0" encoding="UTF-8"?> <doctrine-mongo-mapping ...> <document name="PHPTourConferencier"> <field fieldName="id" id="true" /> <field fieldName="nom" type="string" /> <field fieldName="prenom" type="string" /> <field fieldName="entreprise" type="string" /> </document> </doctrine-mongo-mapping> PHPTourConferencier: fields: id: type: id id: true nom: type: string prenom: type: string entreprise: type: string
  • 59. DocumentManager : initialisation $config = new DoctrineODMMongoDBConfiguration(); $config->setProxyDir('path/to/geearate/proxies'); $config->setProxyNamespace('Proxies'); $config->setHydratorDir('path/to/generate/hydrators'); $config->setHydratorNamespace('Hydrators'); $reader = new DoctrineCommonAnnotationsAnnotationReader(); $reader->setDefaultAnnotationNamespace('DoctrineODMMongoDBMapping'); $config->setMetadataDriverImpl(new AnnotationDriver($reader)); $dm = DoctrineODMMongoDB DocumentManager::create(new Mongo(), $config); (), $config);
  • 60. DocumentManager ● Accès central de la persistance des données ● Implemente le pattern Unif Of Work ● Gestion de l'état des objets en mémoire (NEW, MANAGED, DETACHED ou REMOVED)
  • 61. Requêtes avec Doctrine // SELECT ALL $conferences = $dm->getRepository('PHPTourConference')->findBy(array()); // SELECT BY ID $conference = $dm->find(' PHPTourConference', $id); // SELECT BY CRITERIA $conference = $dm->getRepository('PHPTourConference') ->findOneBy(array('titre' => 'Hello $Mongo')); // INSERT OR UPDATE $dm->persist($conference); // DELETE $dm->remove($conference);
  • 62. GridFS $conference = $dm->createQueryBuilder ('PHPTourConference') ->field('titre') ->equals('hello $Mongo;') ->getQuery() ->execute() ->getSingleResult(); header('Content-type: application/pdf'); echo $conference->getSlides()->getFichier()->getBytes();
  • 63. Performances - Indexes bd.Collection.ensureIndex({monChamp : 1}) bd.Collection.dropIndex() bd.Collection.dropIndex({monChamp : 1}) ● Opération coûteuse et bloquante ● Peut être réalisée en tâche de fond db.Collection.ensureIndex({monChamp : 1}, {background : 1})
  • 64. Performances - Indexes (2) ● Index sur plusieurs champs db.ensureIndex({nom : 1, prenom : 1}); ● Assurer l'unicité db.ensureIndex({nom : 1, prenom : 1}, {unique : 1});
  • 65. Performances - Indexes (3) Pas toujours efficaces ● négations ($ne, $not, ...) ● Opérations arythmétiques ($mod, ...) ● Map / Reduce (boite noire pour l'optimiseur) ● La plupart des expressions rationelles (/a/)
  • 66. Outils dev. et admin. ● RockMongo ● Fang of Mongo ● MongoExplorer (silverlight) ● MongoHub ● PHPMoAdmin ● Meclipse ● MongoVue
  • 68. Photographies Hangin by a thread - http://www.500px.com/photo/3159488 - Scott Smora Pacific coast rail line - http://www.500px.com/photo/1739071 - Lachlan Crossroads - http://500px.com/photo/206202 - DMitry Kot Old book - http://500px.com/photo/841759 - Amar Chauhan Inappropriately Dressed - White dress fast bike - http://500px.com/photo/330960 - Apollinaria Toloraya junction - http://500px.com/photo/3113517 - Kai Ziehl the cube - http://500px.com/photo/1365861 - Stephen L. Sans titre - http://500px.com/photo/1125283 - James Tatum What's in the box?- http://500px.com/photo/1292897 - Andrew Do gears of war - http://500px.com/photo/672778 - Dave Kane Link - http://500px.com/photo/514318 - Djura Stankovic Photography Russian dolls lined up - http://www.flickr.com/photos/sunnyuk/3240916291/ - sunnyUK records - http://500px.com/photo/1084138 - Jackson Carson microphone - http://www.500px.com/photo/1910034 - Tchon T