GridFS в Spring Data MongoDB

GridFS в Spring Data MongoDB

1. обзор

В этом руководстве будет изучен один изcore features of Spring Data MongoDB: interacting with*GridFS*.

Спецификация хранилища GridFS в основном используется для работы с файлами, размер которых превышает ограничение на размерBSON-документа, равное 16 МБ. А Spring Data предоставляет интерфейсGridFsOperations и его реализацию– GridFsTemplate - для простого взаимодействия с этой файловой системой.

2. конфигурация

2.1. Конфигурация XML

Начнем с простой конфигурации XML дляGridFsTemplate:


    
    

Аргументы конструктора дляGridFsTemplate включают ссылки bean-компонентов наmongoDbFactory, который создает базу данных Mongo, иmongoConverter, который преобразует типы Java и MongoDB. Их определения бинов приведены ниже.




    

2.2. Конфигурация Java

Давайте создадим аналогичную конфигурацию, только на Java:

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

Для этой конфигурации мы использовалиmongoDbFactory иmappingMongoConverter изorg.springframework.data.mongodb.config.AbstractMongoConfiguration.

3. GridFsTemplate Основные методы

3.1. storeс

Методstore сохраняет файл в MongoDB.

Предположим, у нас есть пустая база данных и мы хотим сохранить в ней файл:

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

Обратите внимание, что мы можем сохранить дополнительные метаданные вместе с файлом, передавDBObject методуstore. В нашем примереDBObject может выглядеть примерно так:

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

GridFS использует две коллекции для хранения метаданных файла и его содержимого. Метаданные файла хранятся в коллекцииfiles, а содержимое файла хранится в коллекцииchunks. Обе коллекции имеют префиксfs.

Если мы выполним команду MongoDBdb[‘fs.files'].find(), мы увидим коллекциюfs.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"
}

Командаdb[‘fs.chunks'].find() извлекает содержимое файла:

{
    "_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 возвращает ровно один документ, удовлетворяющий указанным критериям запроса.

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

Код выше вернет запись результата, которая была добавлена ​​в примере выше. Если база данных содержит более одной записи, которая соответствует запросу, она вернет только один документ. Конкретная возвращаемая запись будет выбрана в соответствии с естественным порядком (порядок, в котором документы были сохранены в базе данных).

3.3. findс

find выбирает документы из коллекции и возвращает курсор к выбранным документам.

Предположим, у нас есть следующая база данных, содержащая 2 записи:

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

Если мы используемGridFsTemplate для выполнения следующего запроса:

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

Полученный список должен содержать две записи, поскольку мы не указали никаких критериев.

Мы, конечно, можем предоставить некоторые критерии для методаfind. Например, если мы хотим получить файлы, метаданные которых содержат пользователей с именемalex,, код будет следующим:

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

Полученный список будет содержать только одну запись.

3.4. deleteс

delete удаляет документы из коллекции.

Используя базу данных из предыдущего примера, предположим, что у нас есть код:

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

После выполненияdelete в базе данных остается только одна запись:

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

с кусками:

{
    "_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 возвращает всеGridFsResource с заданным шаблоном имени файла.

Предположим, у нас есть следующие записи в базе данных:

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

Теперь давайте выполнимgetResources, используя шаблон файла:

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

Это вернет две записи, имена файлов которых начинаются с «test» (в данном случае они обе имеют имяtest.png).

4. GridFSFile Основные методы

APIGridFSFile тоже довольно прост:

  • getFilename - получает имя файла

  • getMetaData - получает метаданные для данного файла

  • containsField - определяет, содержит ли документ поле с заданным именем

  • get - получает поле от объекта по имени

  • getId - получает идентификатор объекта файла

  • keySet - получает имена полей объекта

5. Заключение

В этой статье мы рассмотрели возможности MongoDBGridFS и способы взаимодействия с ними с помощью Spring Data MongoDB.

Реализация всех этих примеров и фрагментов кодаcan be found inmy github project - это проект на основе Eclipse, поэтому его должно быть легко импортировать и запускать как есть.

Related