Premières requêtes avec le shell mongoDB

Dynamic Schema (Schema Free)

MongoDB est composé de bases de données, de collections (équivalent à des tables dans le domaine relationnel) et des index ce qui ne nous perturbe pas franchement par rapport à des bases de données relationnelles classiques. Dans certains cas les objets peuvent être créés de manière implicite lors de la première insertion. Après leur création, elles existeront dans les catalogues du système. On pourra alors lister ces données grâce aux commandes suivantes :


db.systems.collections

db.system.indexes

Les collections contiennent des documents de type BSON qui sont composés de champs. Dans mongoDB, il n’y a pas de champs prédéfinis (ce qui n’est pas le cas des cas relationnels). Il n’y a pas de schéma prédéfini pour les documents et ainsi, les champs et le type de données qu’ils représentent peuvent varier. On peut alors oublier la notion propre au domaine relationnel d’ « alter table ».

Dans mongoDB, nous n’aurons pas la notion « alter table » qui ajoute une colonne à notre collection. On se contentera simplement d’insérer des objets qui ont des données potentiellement différentes. Cette flexibilité signifie que la modification de la structure d’une base de données mongoDB est très simple en pratique.

Insérer des données dans une collection

Nous allons alors créer une collection « things » et y insérer des données. On créera alors deux objets « j » et « t » et ainsi, on les insèrera dans la collection précédemment créée (« things »)

Dans l’exemple suivant, le symbole « > » représente les commandes que nous taperons dans le shell. Les lignes qui ne commencent pas par ce symbole correspondent donc à la réponse du shell.


> j = { name : "mongo" };

{"name" : "mongo"}

> t = { x : 3 };

{ "x" : 3  }

> db.things.save(j);

> db.things.save(t);

> db.things.find();

{ "_id" : ObjectId("4c2209f9f3924d31102bd84a"), "name" : "mongo" }

{ "_id" : ObjectId("4c2209fef3924d31102bd84b"), "x" : 3 }
>

Quelques remarques :

  • Nous n’avons pas défini la collection « things » au préalable. On s’est contenté d’y ajouter des données et mongoDB s’est chargé de créer cette collection à la première insertion
  • Les documents que nous avons insérés ont des champs complètement différents. En pratique, on stockera les documents qui ont une structure similaire dans les collections
  • Lorsque l’on a inséré nos objets dans la base, mongoDB leur a affecté un « object ID » (s’ils n’en possédaient pas déjà un) en leur ajoutant un champ « _id »
  • Il est tout à fait normal que les valeurs d’objectId données par mongoDB soient différentes.

Ajoutons maintenant quelques données dans notre collection :


> for (var i = 1; i <= 20; i++) db.things.save({x : 4, j : i});

> db.things.find();

{ "_id" : ObjectId("4c2209f9f3924d31102bd84a"), "name" : "mongo" }

{ "_id" : ObjectId("4c2209fef3924d31102bd84b"), "x" : 3 }

{ "_id" : ObjectId("4c220a42f3924d31102bd856"), "x" : 4, "j" : 1 }

{ "_id" : ObjectId("4c220a42f3924d31102bd857"), "x" : 4, "j" : 2 }

...

{ "_id" : ObjectId("4c220a42f3924d31102bd866"), "x" : 4, "j" : 17 }

{ "_id" : ObjectId("4c220a42f3924d31102bd867"), "x" : 4, "j" : 18 }

has more

On remarquera que l’on peut réellement utiliser javascript comme un langage et faire des opérations dans le shell.

On remarquera également que nous avons inséré 20 données dans la collection things (en plus de celles que nous avions insérées au préalable). Cependant mongoDB ne nous en a affiché que 20 et non pas 22. A la fin, on constate également que mongoDB nous a affiché l’information « has more » ce qui signifie qu’il en a trouvé davantage.

En réalité, mongoDB ne nous affichera au maximum que 20 résultats et si nous souhaitons afficher les suivants, il nous suffira de taper la commande « it » :

{ "_id" : ObjectId("4c220a42f3924d31102bd866"), "x" : 4, "j" : 17 }
{ "_id" : ObjectId("4c220a42f3924d31102bd867"), "x" : 4, "j" : 18 }
has more
> it
{ "_id" : ObjectId("4c220a42f3924d31102bd868"), "x" : 4, "j" : 19 }
{ "_id" : ObjectId("4c220a42f3924d31102bd869"), "x" : 4, "j" : 20 }

En pratique, find() retourne un objet de type curseur. Mais dans le cas précédent, nous n’avons pas affecté ce curseur à une variable. Ainsi, le shell itère automatiquement sur le curseur, en nous donnant le premier lot de résultats, et nous permet de visualiser la suite avec la commande « it ».

Mais on peut directement travailler avec le curseur et c’est ce dont nous parlerons par la suite.

Récupérer des données

Nous allons faire un petit tour d’horizon des méthodes qui vous permettront de récupérer des données simplement.

Comme nous l’avons dit précédemment, nous pouvons manipuler un curseur retourné par la commande « find() ». Empressons nous alors de tester cette méthode :


> var cursor = db.things.find();

> while (cursor.hasNext()) printjson(cursor.next());

{ "_id" : ObjectId("4c2209f9f3924d31102bd84a"), "name" : "mongo" }

{ "_id" : ObjectId("4c2209fef3924d31102bd84b"), "x" : 3 }

{ "_id" : ObjectId("4c220a42f3924d31102bd856"), "x" : 4, "j" : 1 }

{ "_id" : ObjectId("4c220a42f3924d31102bd857"), "x" : 4, "j" : 2 }

{ "_id" : ObjectId("4c220a42f3924d31102bd858"), "x" : 4, "j" : 3 }
...
{ "_id" : ObjectId("4c220a42f3924d31102bd868"), "x" : 4, "j" : 19 }

{ "_id" : ObjectId("4c220a42f3924d31102bd869"), "x" : 4, "j" : 20 }

On remarque alors que toutes les entrées nous ont été retournées. Il n’y a alors pas de limite d’affichage dans le shell avec cette méthode et il n’y a alors pas besoin d’utiliser la commande « it » dont nous avons parlé précédemment.

De la même manière, nous pourrons utiliser la méthode suivante pour afficher tous les résultats :


> db.things.find().forEach(printjson);

Pour récupérer un résultat, nous pouvons alors procéder de la manière suivante :


> var cursor = db.things.find();

> printjson(cursor[4]);

{ "_id" : ObjectId("4c220a42f3924d31102bd858"), "x" : 4, "j" : 3 }

ou encore de la manière suivante :


> var arr = db.things.find().toArray();

> arr[5];

{ "_id" : ObjectId("4c220a42f3924d31102bd859"), "x" : 4, "j" : 4 }