Les collections avec MongoDB

Publié le 29 février 2012 par Cyril Mougel | outils

Cet article est publié sous licence CC BY-NC-SA

Cette semaine, Synbioz invite Cyril Mougel, CTO de bemyboat et et co-fondateur de Supermarmite. Passionné de ruby, MongoBD et de leurs écosystèmes, Cyril est aussi contributeur à un nombre impressionnant de projets open source. Aujourd’hui il nous parle des collections avec MongoDB et de la différence par rapport à une base de données relationnelle. Bonne lecture !

Je suis personnellement un grand fan de MongoDB. Mais finalement, à trop utiliser MongoDB pour tous ses projets, on en oublie certains avantages basiques.

Dernièrement, j’ai réutilisé une base SQL sur un projet et j’ai ainsi retrouvé une fonctionnalité simple de MongoDB que j’utilise intensivement et qui ne peux pas se faire aussi simplement en SQL. C’est la gestion de liste d’éléments.

Je vais montrer ce qu’on peut faire avec MongoDB et ce qu’on doit faire avec SQL pour un exemple simple.

Je souhaite logger en base de données tous les emails qui sont envoyés par mon application. Mais je veux pouvoir lister tous les emails contenant comme destinataire (recipients) un email précis.

En SQL, je dois donc avoir une table emails et une table recipients.

Le schéma de ma table emails sera :

  • id
  • from
  • subject
  • content

et le schéma de ma table recipients sera :

  • id
  • email_id
  • recipient

A chaque nouveau mail, il faut effectuer au moins 2 inserts. Un dans la table emails et l’autre dans la table recipients en liant la clé étrangères email_id avec l’email concerné.

Ensuite à chaque consultation d’email, on doit faire une ou plusieurs requêtes pour obtenir le contenu de l’email et ses recipients. Idem pour connaitre la liste des emails reçus par un email en particulier.

Par contre comment faire avec MongoDB, qui est orienté document ?

C’est très simple, nous n’avons besoin que d’une seule collection. Donc un seul insert et une seule requête pour obtenir exactement les même informations que pour notre exemple en SQL.

Notre document sera ainsi stocké de la façon suivante :

{
'_id':BSON::ObjectId('123ev'),
'subject': 'hello',
'content': 'A good email',
'from': 'cyril.mougel@example.com',
'recipients': ['mongodb-lover@example.com', 'synbioz@example.com']
}

Pour connaitre la liste des emails reçu par ‘mongodb-lover@example.com’ il suffit de faire la requête suivante :

db.emails.find({'recipients': 'mongodb-lover@example.com'})

On peut aussi facilement obtenir la liste des emails reçu par ‘mongodb-lover@example.com’ et ‘synbioz@example.com’

db.emails.find({'recipients': {'$all':['mongodb-lover@example.com', 'synbioz@example.com']}})

Ou encore les emails reçus par mongodb-lover mais pas synbioz:

db.emails.find({'$or': {'recipients': {'$ne': 'synbioz@example.com'}}, {'recipients':'mongodb-lover@example.com'}})

Comme je le montre, on peut tout à fait réaliser cela en SQL, mais c’est plus compliqué à l’insertion comme à la consultation. La gestion documentaire de MongoDB est très pratique dans ce genre de cas.

L’équipe Synbioz.

Libres d’être ensemble.