MongoDB : les bases pour bien débuter (2/3)

Dans le billet précédent, nous avons vu quelques unes des requêtes DDL nous permettant de manipuler les structures élémentaires de MongoDB, comme les bases de données, les collections et les documents. L’heure est maintenant venue de requêter sur nos données !

Le kit MongoDB, qu'on reçoit à toutes les confs (source http://xenodesystems.blogspot.mx/)

Le kit MongoDB, qu’on reçoit à toutes les confs (source http://xenodesystems.blogspot.mx/)

Notre jeu de données de démarrage

Il est très simple :

> db.gens.insert({"nom":"ferrandez"});
> db.gens.insert({"nom":"ferrandez", prenom: "léo"});
> db.gens.insert({"nom":"ferrandez", prenom: "maïa", age:6});
> db.gens.find();
{ "_id" : ObjectId("517a850cb1d6ce34f91af2d1"), "nom" : "ferrandez" }
{ "_id" : ObjectId("517a851eb1d6ce34f91af2d2"), "nom" : "ferrandez", "prenom" : "léo" }
{ "_id" : ObjectId("517a856bb1d6ce34f91af2d4"), "nom" : "ferrandez", "prenom" : "maïa", "age" : 6 }

MongoDB est schema-less (prononcez « skimaless »), nous pouvons donc très bien insérer des documents qui n’ont pas la même structure, regardez bien nos trois documents, ils ne comportent pas le même nombre de champs !

Poser des index

Vous le savez, pour que vos requêtes aient un temps d’exécution satisfaisant (surtout si elle sont appelées fréquemment), il est absolument nécessaire qu’elles s’appuient sur des index. MongoDB dispose d’index au niveau des collections (l’équivalent des tables en SQL). Le champ _id est indexé par défaut et il est impossible de le supprimer.

Sur un seul champ

Pour poser un index sur le champ nom dans l’ordre ascendant (1, ce sera -1 pour DESC) :

db.gens.ensureIndex({nom:1});

Les index composés

Pour poser un index sur les champs nom ET prenom (ASC tous les deux) :

db.gens.ensureIndex({nom:1, prenom:1});

Comme en SQL, si vos requêtes se basent sur prenom, l’index ne sera pas utilisé !
Si vous requêtez sur le nom ou sur le nom ET le prénom, celui-ci sera sollicité.

Les index uniques

Rien de plus simple :

db.gens.ensureIndex({nom:1}, {unique: true});

Ici en réalité la pose de cet index va échouer car notre champ nom contient les mêmes valeurs :

> db.gens.ensureIndex({nom:1}, {unique: true});
E11000 duplicate key error index: gens.gens.$nom_1  dup key: { : "ferrandez" }

Voir les index d’une collection

db.gens.getIndexes();
[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "ns" : "gens.gens",
                "name" : "_id_"
        },
        {
                "v" : 1,
                "key" : {
                        "nom" : 1
                },
                "ns" : "gens.gens",
                "name" : "nom_1"
        },
        {
                "v" : 1,
                "key" : {
                        "nom" : 1,
                        "prenom" : 1
                },
                "ns" : "gens.gens",
                "name" : "nom_1_prenom_1"
        }
]

Supprimer un index

On va supprimer l’index nommé ‘nom_1_prenom_1’ :

> db.gens.dropIndex('nom_1_prenom_1')
{ "nIndexesWas" : 3, "ok" : 1 }
> db.gens.getIndexes();
[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "ns" : "gens.gens",
                "name" : "_id_"
        },
        {
                "v" : 1,
                "key" : {
                        "nom" : 1
                },
                "ns" : "gens.gens",
                "name" : "nom_1"
        }
]

Nous voyons qu’il a été effectivement supprimé (et nous voyons aussi au passage qu’un index est posé par défaut par MongoDB sur _id).

Les requêtes

Sur une seule valeur

Cherchons toutes les personnes qui ont 6 ans :

> db.gens.find({age:6});
{ "_id" : ObjectId("517a856bb1d6ce34f91af2d4"), "nom" : "ferrandez", "prenom" : "maïa", "age" : 6 }

Cherchons toutes les personnes qui s’appellent « ferrandez » :

> db.gens.find({nom:"ferrandez"});
{ "_id" : ObjectId("517a850cb1d6ce34f91af2d1"), "nom" : "ferrandez" }
{ "_id" : ObjectId("517a851eb1d6ce34f91af2d2"), "nom" : "ferrandez", "prenom" : "léo" }
{ "_id" : ObjectId("517a856bb1d6ce34f91af2d4"), "nom" : "ferrandez", "prenom" : "maïa", "age" : 6 }

Sur deux valeurs

Cherchons toutes les personnes qui ont 6 ans et qui s’appellent « ferrandez » :

> db.gens.find({nom:"ferrandez", age:6});
{ "_id" : ObjectId("517a856bb1d6ce34f91af2d4"), "nom" : "ferrandez", "prenom" : "maïa", "age" : 6 }

Avec des opérateurs de comparaison

Cherchons tous les « ferrandez » qui ont plus de 6 ans (gt = greater than)

> db.gens.find({nom:"ferrandez", age: {$gt: 6}});

Cherchons tous les « ferrandez » qui ont moins de 6 ans (lt = less than)

> db.gens.find({nom:"ferrandez", age: {$lt: 6}});

Ces deux requêtes ne ramènent aucun résultat, ce qui n’est pas le cas des suivantes avec l’égalité…

> db.gens.find({nom:"ferrandez", age: {$lte: 6}});
{ "_id" : ObjectId("517a856bb1d6ce34f91af2d4"), "nom" : "ferrandez", "prenom" : "maïa", "age" : 6 }
> db.gens.find({nom:"ferrandez", age: {$gte: 6}});
{ "_id" : ObjectId("517a856bb1d6ce34f91af2d4"), "nom" : "ferrandez", "prenom" : "maïa", "age" : 6 }

L’équivalent du IN SQL

Les gens dont l’âge est 6, 7 ou 8 :

> db.gens.find({age: {$in: [6, 7, 8]}});
{ "_id" : ObjectId("517a856bb1d6ce34f91af2d4"), "nom" : "ferrandez", "prenom" : "maïa", "age" : 6 }

Les expressions régulières (regexp)

Les gens dont le nom commence par la lettre f :

> db.gens.find({nom:/^f/});
{ "_id" : ObjectId("517a850cb1d6ce34f91af2d1"), "nom" : "ferrandez" }
{ "_id" : ObjectId("517a851eb1d6ce34f91af2d2"), "nom" : "ferrandez", "prenom" : "léo" }
{ "_id" : ObjectId("517a856bb1d6ce34f91af2d4"), "nom" : "ferrandez", "prenom" : "maïa", "age" : 6 }

2 réflexions sur « MongoDB : les bases pour bien débuter (2/3) »

  1. yannick

    pour ouvrir les commentaires ..
    alors là je me suis régalé,
    la première partie m’a plu mais là la simplicité de Mongo semble évidente, et je réalise que JavaScript est un language très polyvalent et puissant !!!
    Bon, passons à la suite 🙂

    Répondre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.