GridFS no Spring Data MongoDB

GridFS no Spring Data MongoDB

1. Visão geral

Este tutorial irá explorar um doscore features of Spring Data MongoDB: interacting with*GridFS*.

A especificação de armazenamento GridFS é usada principalmente para trabalhar com arquivos que excedem o limite de tamanho deBSON-document de 16 MB. E Spring Data fornece uma interfaceGridFsOperations e sua implementação– GridFsTemplate - para interagir facilmente com este sistema de arquivos.

2. Configuração

2.1. Configuração XML

Vamos começar com a configuração XML simples paraGridFsTemplate:


    
    

Os argumentos do construtor paraGridFsTemplate incluem referências de bean amongoDbFactory, que cria um banco de dados Mongo, emongoConverter, que converte entre os tipos Java e MongoDB. Suas definições de bean estão abaixo.




    

2.2. Configuração Java

Vamos criar uma configuração semelhante, apenas com Java:

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

Para esta configuração, usamosmongoDbFactoryemappingMongoConverter deorg.springframework.data.mongodb.config.AbstractMongoConfiguration.

3. Métodos Básicos deGridFsTemplate

3.1. store

O métodostore salva um arquivo no MongoDB.

Suponha que tenhamos um banco de dados vazio e desejemos armazenar um arquivo nele:

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

Observe que podemos salvar metadados adicionais junto com o arquivo, passandoDBObject para o métodostore. Para nosso exemplo, oDBObject pode ser parecido com isto:

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

GridFS usa duas coleções para armazenar os metadados do arquivo e seu conteúdo. Os metadados do arquivo são armazenados na coleçãofiles, e o conteúdo do arquivo é armazenado na coleçãochunks. Ambas as coleções são prefixadas comfs.

Se executarmos o comando MongoDBdb[‘fs.files'].find(), veremos a coleçãofs.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"
}

O comandodb[‘fs.chunks'].find() recupera o conteúdo do arquivo:

{
    "_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 retorna exatamente um documento que satisfaz os critérios de consulta especificados.

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

O código acima retornará o registro de resultado que foi adicionado no exemplo acima. Se o banco de dados contivesse mais de um registro que correspondesse à consulta, ele retornaria apenas um documento. O registro específico retornado seria selecionado de acordo com a ordem natural (a ordem em que os documentos foram armazenados no banco de dados).

3.3. find

find seleciona documentos de uma coleção e retorna um cursor para os documentos selecionados.

Suponha que tenhamos o seguinte banco de dados, contendo 2 registros:

[
    {
        "_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"
    }
]

Se usarmosGridFsTemplate para executar a seguinte consulta:

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

A lista resultante deve conter dois registros, pois não fornecemos critérios.

Podemos, é claro, fornecer alguns critérios para o métodofind. Por exemplo, se quisermos obter arquivos cujos metadados contenham usuários com o nomealex,, o código seria:

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

A lista resultante conterá apenas um registro.

3.4. delete

delete remove documentos de uma coleção.

Usando o banco de dados do exemplo anterior, suponha que tenhamos o código:

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

Depois de executardelete, apenas um registro permanece no banco de dados:

{
    "_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"
}

com pedaços:

{
    "_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 retorna todos osGridFsResource com o padrão de nome de arquivo fornecido.

Suponha que tenhamos os seguintes registros no banco de dados:

[
   {
       "_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"
    }
]

Agora vamos executargetResources usando um padrão de arquivo:

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

Isso retornará os dois registros cujos nomes de arquivo começam com “teste” (neste caso, ambos são nomeadostest.png).

4. Métodos Básicos deGridFSFile

A APIGridFSFile também é bastante simples:

  • getFilename - obtém o nome do arquivo

  • getMetaData - obtém os metadados para o arquivo fornecido

  • containsField - determina se o documento contém um campo com o nome fornecido

  • get - obtém um campo do objeto por nome

  • getId - obtém o ID do objeto do arquivo

  • keySet - obtém os nomes dos campos do objeto

5. Conclusão

Neste artigo, examinamos os recursosGridFS do MongoDB e como interagir com eles usando o Spring Data MongoDB.

A implementação de todos esses exemplos e fragmentos de códigocan be found inmy github project - este é um projeto baseado em Eclipse, portanto, deve ser fácil de importar e executar como está.