Blog ENI : Toute la veille numérique !
-25€ dès 75€ sur les livres en ligne, vidéos... avec le code FUSEE25. J'en profite !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. MongoDB
  3. Gérer des fichiers binaires avec GridFS
Extrait - MongoDB Comprendre et optimiser l'exploitation de vos données (avec exercices et corrigés)
Extraits du livre
MongoDB Comprendre et optimiser l'exploitation de vos données (avec exercices et corrigés) Revenir à la page d'achat du livre

Gérer des fichiers binaires avec GridFS

Introduction

MongoDB intègre de façon native un mécanisme de gestion des fichiers binaires dont la taille dépasse les 16 mégaoctets : son nom est GridFS.

Principe de fonctionnement

Le mode opératoire de GridFS consiste à éclater un fichier de très grande taille en plusieurs morceaux (chunks en anglais) qui sont en fait des documents dont la taille par défaut est fixée à 255 kilooctets. GridFS est en quelque sorte une couche de gestion de fichiers qui vient se superposer à MongoDB, qui lui ne fonctionne qu’avec des documents.

Si GridFS a pour raison d’être d’aider à stocker des fichiers volumineux comme des fichiers audio ou vidéo, rien ne vous empêche cependant de l’utiliser avec des fichiers de toute taille ou nature (texte pur par exemple), y compris inférieure aux 255 kilo-octets qui constituent la taille par défaut d’un chunk. Évidemment, cette utilisation ne présente pour ainsi dire aucun intérêt, car GridFS reste dimensionné pour les fichiers dont le poids est supérieur à 16 mégaoctets, mais elle peut être envisagée et nous le verrons dans l’exemple d’utilisation qui suit, pour des raisons de pratiques. Si le fichier que vous souhaitez stocker a un poids inférieur à 16 mégaoctets, tournez-vous plutôt vers le type BinData qui stocke l’information sous forme des chaînes de caractères binaires codées en base64.

GridFS peut avoir des avantages si on le compare à...

Les collections chunks et files

GridFS s’appuie sur deux collections pour gérer ces gros fichiers : la première, nommée chunks, héberge les documents qui constituent le fichier tandis que la seconde, nommée files, contient les métadonnées associées au fichier. Dans chunks, nous trouverons notamment le numéro de séquence du morceau de fichier et son contenu sous forme binaire (BSON, qui d’autre ?) et dans files, des informations telles que la date de téléchargement, la taille de chaque morceau de fichier ou le nom du fichier éclaté en plusieurs chunks.

Ces collections doivent être indexées et ces index sont créés automatiquement par les pilotes si vous utilisez MongoDB depuis votre langage de développement favori. Toutefois, si vous opérez comme nous le faisons à partir du shell, il se peut que vous ayez à les créer vous-mêmes à l’aide des commandes suivantes :

db.fs.chunks.createIndex( { files_id: 1, n: 1 }, { unique: true } ); 
db.fs.files.createIndex( { filename: 1, uploadDate: 1 } ); 

Ces deux collections peuvent être shardées si vous le souhaitez : pour chunks la clé de sharding pourra être constituée du champ files_id éventuellement couplé à un autre tandis que pour files...

Utiliser mongofiles

Le programme mongofiles, fourni d’office avec toute distribution de MongoDB, et autonome car ne s’utilisant pas depuis le shell, vous permet d’interagir en toute simplicité avec la base de données. Vous trouverez cet exécutable dans le répertoire de votre installation.

1. Ajouter un fichier à GridFS

La commande peut vous permettre de déposer un fichier dans GridFS, sa syntaxe est très simple :

mongofiles put < chemin vers le fichier > 

Créons un fichier texte rudimentaire et déposons-le ensuite (la réponse du programme figure en gras) :

echo "Test Mongofiles" > /tmp/petitfichier.txt 
mongofiles put /tmp/petitfichier.txt 
connected to: localhost 
added file: /tmp/petitfichier.txt 

Notre fichier a bien été ajouté. Utilisons maintenant le shell pour vérifier sa présence dans chacune des collections gérées par GridFS. Tout d’abord, dans la collection chunks dont le namespace complet est db.fs.chunks :

db.fs.chunks.find(); 
{ 
   "_id" : ObjectId("5d1c70936cc2f85b652398c9"), 
   "files_id" : ObjectId("5d1c70936cc2f85b652398c8"), 
   "n" : 0,   "data" : BinData(0,"VGVzdCBNb25nb2ZpbGVzCg==")  
} 

La valeur du champ n nous indique que cet unique chunk porte le numéro de séquence 0, ce qui est parfaitement cohérent. Le champ data contient peu de données binaires, ce qui est plutôt normal...