GridFS dans Spring Data MongoDB

GridFS dans Spring Data MongoDB

1. Vue d'ensemble

Ce tutoriel explorera l'un descore features of Spring Data MongoDB: interacting with*GridFS*.

La spécification de stockage GridFS est principalement utilisée pour travailler avec des fichiers qui dépassent la limite de taille du documentBSON de 16 Mo. Et Spring Data fournit une interfaceGridFsOperations et son implémentation– GridFsTemplate - pour interagir facilement avec ce système de fichiers.

2. Configuration

2.1. Configuration XML

Commençons par la configuration XML simple pour lesGridFsTemplate:


    
    

Les arguments du constructeur pour lesGridFsTemplate incluent des références de bean àmongoDbFactory, qui crée une base de données Mongo, etmongoConverter, qui convertit entre les types Java et MongoDB. Leurs définitions de haricots sont ci-dessous.




    

2.2. Configuration Java

Créons une configuration similaire, uniquement avec Java:

@Bean
public GridFsTemplate gridFsTemplate() throws Exception {
    return new GridFsTemplate(mongoDbFactory(), mappingMongoConverter());
}

Pour cette configuration, nous avons utilisémongoDbFactory etmappingMongoConverter deorg.springframework.data.mongodb.config.AbstractMongoConfiguration.

3. Méthodes de base deGridFsTemplate

3.1. store

La méthodestore enregistre un fichier dans MongoDB.

Supposons que nous ayons une base de données vide et que nous souhaitons y stocker un fichier:

InputStream inputStream = new FileInputStream("src/main/resources/test.png");
gridFsTemplate.store(inputStream, "test.png", "image/png", metaData).toString();

Notez que nous pouvons enregistrer des métadonnées supplémentaires avec le fichier en passant unDBObject à la méthodestore. Pour notre exemple, lesDBObject peuvent ressembler à ceci:

DBObject metaData = new BasicDBObject();
metaData.put("user", "alex");

GridFS utilise deux collections pour stocker les métadonnées du fichier et son contenu. Les métadonnées du fichier sont stockées dans la collectionfiles et le contenu du fichier est stocké dans la collectionchunks. Les deux collections sont préfixées avecfs.

Si nous exécutons la commande MongoDBdb[‘fs.files'].find(), nous verrons la collectionfs.files:

{
    "_id" : ObjectId("5602de6e5d8bba0d6f2e45e4"),
    "metadata" : {
        "user" : "alex"
    },
    "filename" : "test.png",
    "aliases" : null,
    "chunkSize" : NumberLong(261120),
    "uploadDate" : ISODate("2015-09-23T17:16:30.781Z"),
    "length" : NumberLong(855),
    "contentType" : "image/png",
    "md5" : "27c915db9aa031f1b27bb05021b695c6"
}

La commandedb[‘fs.chunks'].find() récupère le contenu du fichier:

{
    "_id" : ObjectId("5602de6e5d8bba0d6f2e45e4"),
    "files_id" : ObjectId("5602de6e5d8bba0d6f2e45e4"),
    "n" : 0,
    "data" :
    {
        "$binary" : "/9j/4AAQSkZJRgABAQAAAQABAAD/4QAqRXhpZgAASUkqAAgAAAABADEBAgAHAAAAGgAAAAAAAABHb29nbGUAAP/bAIQAAwICAwICAwMDAwQDAwQFCAUFBAQFCgcHBggM
          CgwMCwoLCw0OEhANDhEOCwsQFhARExQVFRUMDxcYFhQYEhQVFAEDBAQGBQUJBgYKDw4MDhQUFA8RDQwMEA0QDA8VDA0NDw0MDw4MDA0ODxAMDQ0MDAwODA8MDQ4NDA0NDAwNDAwQ/8AA
          EQgAHAAcAwERAAIRAQMRAf/EABgAAQEBAQEAAAAAAAAAAAAAAAgGBwUE/8QALBAAAgEDAgQFAwUAAAAAAAAAAQIDBAURBiEABwgSIjFBYXEyUYETFEKhw
          f/EABoBAAIDAQEAAAAAAAAAAAAAAAMEAQIFBgD/xAAiEQACAgEDBAMAAAAAAAAAAAAAAQIRAyIx8BJRYYETIUH/2gAMAwEAAhEDEQA/AHDyq1Bb6GjFPMAszLkZHHCTi1I6O
          cXOFRZ1ZqoX6aqzRClkhb9MGVh2SsNyVI/hjG5389tuGcUaLK1GmFfpn5r3rnXpfV82pGtS3a0XmaGOO3zguKV1SWDwBQDH2uUWTOWMZzuM8bS0VQtJKRb2li9LL3l+4VNQPEfQTOB/WO
          G1K0JtUzwad1eZaYBiqzL4S2N8cZUsa7DqlRGdWvMq5aX6b9Tvb5pIZbggt7VcU3YacSkDbfuLNuu3lkk+98GNfIrLt2gK9K/NWl5Z87Ldebj3R0NTa2tVVKhOI0KoQ5AG4DRqSPk+gHGn
          khUPYNOx92vW9PcrdDW0FUJqOp7po5ETIYMxOdyOAK0qAvcgKPWa0oMTo7SEYDKPp98/5wPoJsx3rZ1wLhojS9iinLD9w9W47iSwVe0Z3wfrPoce2eC4I6rCX9MxrpUpWqudNunUosNLR1EkiyIGDqUKF
          fyZB+AeG80riueQdVfObC/tN1pLdaLfSxMiRQ08aIg2CjtGAB9uEyCSqSWujICUXwghT57A5+ePEoMvUdc5a3XlSsgUhZGjGM/TGAqjz+SfuT7DDmGC6WzzeyOv0+2amOrr3KylzTUwjjDeWGbJJ9/COI
          yvRFFv1iRsVGDaqYGWVsIoBZydsDhQGf/Z",
        "$type" : "00"
    }
}

3.2. findOne

findOne renvoie exactement un document qui satisfait les critères de requête spécifiés.

String id = "5602de6e5d8bba0d6f2e45e4";
GridFSFile gridFsFile = gridFsTemplate.findOne(new Query(Criteria.where("_id").is(id)));

Le code ci-dessus renverra l'enregistrement de résultat ajouté dans l'exemple ci-dessus. Si la base de données contenait plusieurs enregistrements correspondant à la requête, elle ne renverrait qu'un seul document. L'enregistrement spécifique renvoyé serait sélectionné en fonction de l'ordre naturel (l'ordre dans lequel les documents étaient stockés dans la base de données).

3.3. find

find sélectionne des documents dans une collection et renvoie un curseur sur les documents sélectionnés.

Supposons que nous ayons la base de données suivante, contenant 2 enregistrements:

[
    {
        "_id" : ObjectId("5602de6e5d8bba0d6f2e45e4"),
        "metadata" : {
            "user" : "alex"
        },
        "filename" : "test.png",
        "aliases" : null,
        "chunkSize" : NumberLong(261120),
        "uploadDate" : ISODate("2015-09-23T17:16:30.781Z"),
        "length" : NumberLong(855),
        "contentType" : "image/png",
        "md5" : "27c915db9aa031f1b27bb05021b695c6"
    },
    {
        "_id" : ObjectId("5702deyu6d8bba0d6f2e45e4"),
        "metadata" : {
            "user" : "david"
        },
        "filename" : "test.png",
        "aliases" : null,
        "chunkSize" : NumberLong(261120),
        "uploadDate" : ISODate("2015-09-23T17:16:30.781Z"),
        "length" : NumberLong(855),
        "contentType" : "image/png",
        "md5" : "27c915db9aa031f1b27bb05021b695c6"
    }
]

Si nous utilisons lesGridFsTemplate pour exécuter la requête suivante:

List fileList = new ArrayList();
gridFsTemplate.find(new Query()).into(fileList);

La liste résultante doit contenir deux enregistrements, car nous n’avons fourni aucun critère.

Nous pouvons, bien entendu, fournir certains critères à la méthodefind. Par exemple, si nous souhaitons obtenir des fichiers dont les métadonnées contiennent des utilisateurs avec le nomalex,, le code serait:

List gridFSFiles = new ArrayList();
gridFsTemplate.find(new Query(Criteria.where("metadata.user").is("alex"))).into(gridFSFiles);

La liste résultante ne contiendra qu'un seul enregistrement.

3.4. delete

delete supprime les documents d'une collection.

En utilisant la base de données de l'exemple précédent, supposons que nous ayons le code:

String id = "5702deyu6d8bba0d6f2e45e4";
gridFsTemplate.delete(new Query(Criteria.where("_id").is(id)));

Après l'exécution dedelete, il ne reste qu'un seul enregistrement dans la base de données:

{
    "_id" : ObjectId("5702deyu6d8bba0d6f2e45e4"),
    "metadata" : {
        "user" : "alex"
    },
    "filename" : "test.png",
    "aliases" : null,
    "chunkSize" : NumberLong(261120),
    "uploadDate" : ISODate("2015-09-23T17:16:30.781Z"),
    "length" : NumberLong(855),
    "contentType" : "image/png",
    "md5" : "27c915db9aa031f1b27bb05021b695c6"
}

avec des morceaux:

{
    "_id" : ObjectId("5702deyu6d8bba0d6f2e45e4"),
    "files_id" : ObjectId("5702deyu6d8bba0d6f2e45e4"),
    "n" : 0,
    "data" :
    {
        "$binary" : "/9j/4AAQSkZJRgABAQAAAQABAAD/4QAqRXhpZgAASUkqAAgAAAABADEBAgAHAAAAGgAAAAAAAABHb29nbGUAAP/bAIQAAwICAwICAwMDAwQDAwQFCAUFBAQFCgcHBggM
          CgwMCwoLCw0OEhANDhEOCwsQFhARExQVFRUMDxcYFhQYEhQVFAEDBAQGBQUJBgYKDw4MDhQUFA8RDQwMEA0QDA8VDA0NDw0MDw4MDA0ODxAMDQ0MDAwODA8MDQ4NDA0NDAwNDAwQ/8AA
          EQgAHAAcAwERAAIRAQMRAf/EABgAAQEBAQEAAAAAAAAAAAAAAAgGBwUE/8QALBAAAgEDAgQFAwUAAAAAAAAAAQIDBAURBiEABwgSIjFBYXEyUYETFEKhw
          f/EABoBAAIDAQEAAAAAAAAAAAAAAAMEAQIFBgD/xAAiEQACAgEDBAMAAAAAAAAAAAAAAQIRAyIx8BJRYYETIUH/2gAMAwEAAhEDEQA/AHDyq1Bb6GjFPMAszLkZHHCTi1I6O
          cXOFRZ1ZqoX6aqzRClkhb9MGVh2SsNyVI/hjG5389tuGcUaLK1GmFfpn5r3rnXpfV82pGtS3a0XmaGOO3zguKV1SWDwBQDH2uUWTOWMZzuM8bS0VQtJKRb2li9LL3l+4VNQPEfQTOB/WO
          G1K0JtUzwad1eZaYBiqzL4S2N8cZUsa7DqlRGdWvMq5aX6b9Tvb5pIZbggt7VcU3YacSkDbfuLNuu3lkk+98GNfIrLt2gK9K/NWl5Z87Ldebj3R0NTa2tVVKhOI0KoQ5AG4DRqSPk+gHGn
          khUPYNOx92vW9PcrdDW0FUJqOp7po5ETIYMxOdyOAK0qAvcgKPWa0oMTo7SEYDKPp98/5wPoJsx3rZ1wLhojS9iinLD9w9W47iSwVe0Z3wfrPoce2eC4I6rCX9MxrpUpWqudNunUosNLR1EkiyIGDqUKF
          fyZB+AeG80riueQdVfObC/tN1pLdaLfSxMiRQ08aIg2CjtGAB9uEyCSqSWujICUXwghT57A5+ePEoMvUdc5a3XlSsgUhZGjGM/TGAqjz+SfuT7DDmGC6WzzeyOv0+2amOrr3KylzTUwjjDeWGbJJ9/COI
          yvRFFv1iRsVGDaqYGWVsIoBZydsDhQGf/Z",
        "$type" : "00"
    }
}

3.5. getResources

getResources renvoie tous lesGridFsResource avec le modèle de nom de fichier donné.

Supposons que nous ayons les enregistrements suivants dans la base de données:

[
   {
       "_id" : ObjectId("5602de6e5d8bba0d6f2e45e4"),
       "metadata" : {
           "user" : "alex"
       },
       "filename" : "test.png",
       "aliases" : null,
       "chunkSize" : NumberLong(261120),
       "uploadDate" : ISODate("2015-09-23T17:16:30.781Z"),
       "length" : NumberLong(855),
       "contentType" : "image/png",
       "md5" : "27c915db9aa031f1b27bb05021b695c6"
   },
   {
       "_id" : ObjectId("5505de6e5d8bba0d6f8e4574"),
       "metadata" : {
           "user" : "david"
       },
       "filename" : "test.png",
       "aliases" : null,
       "chunkSize" : NumberLong(261120),
       "uploadDate" : ISODate("2015-09-23T17:16:30.781Z"),
       "length" : NumberLong(855),
       "contentType" : "image/png",
       "md5" : "27c915db9aa031f1b27bb05021b695c6"
    },
    {
       "_id" : ObjectId("5777de6e5d8bba0d6f8e4574"),
       "metadata" : {
           "user" : "eugen"
       },
       "filename" : "example.png",
       "aliases" : null,
       "chunkSize" : NumberLong(261120),
       "uploadDate" : ISODate("2015-09-23T17:16:30.781Z"),
       "length" : NumberLong(855),
       "contentType" : "image/png",
       "md5" : "27c915db9aa031f1b27bb05021b695c6"
    }
]

Maintenant, exécutonsgetResources en utilisant un modèle de fichier:

GridFsResource[] gridFsResource = gridFsTemplate.getResources("test*");

Cela renverra les deux enregistrements dont les noms de fichiers commencent par «test» (dans ce cas, ils sont tous deux nomméstest.png).

4. Méthodes de base deGridFSFile

L'APIGridFSFile est également assez simple:

  • getFilename - obtient le nom de fichier du fichier

  • getMetaData - récupère les métadonnées pour le fichier donné

  • containsField - détermine si le document contient un champ avec le nom donné

  • get - obtient un champ de l'objet par son nom

  • getId - obtient l'ID d'objet du fichier

  • keySet - récupère les noms de champ de l'objet

5. Conclusion

Dans cet article, nous avons examiné les fonctionnalitésGridFS de MongoDB et comment interagir avec elles à l'aide de Spring Data MongoDB.

L'implémentation de tous ces exemples et extraits de codecan be found inmy github project - il s'agit d'un projet basé sur Eclipse, il devrait donc être facile à importer et à exécuter tel quel.