Рубрики
Без рубрики

GridFS в весенних данных MongoDB

Краткое руководство по взаимодействию с GridFS с помощью Spring Data MongoDB.

Автор оригинала: baeldung.

1. Обзор

В этом уроке будет рассмотрена одна из основных функций Spring Data MongoDB: взаимодействие с GridFS .

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

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

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

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


    
    

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




    

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

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

@Configuration
@EnableMongoRepositories(basePackages = "com.baeldung.repository")
public class MongoConfig extends AbstractMongoClientConfiguration {
    @Autowired
    private MappingMongoConverter mongoConverter;

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

Для этой конфигурации мы использовали метод MongoDbFactory() и автоматически подключили их mappingmongoconverter , определенный в родительском классе AbstractMongoClientConfiguration .

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

3.1. магазин

Метод 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 .

Если мы выполним команду MongoDB db[‘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 выбирает документы из коллекции и возвращает курсор к выбранным документам.

Предположим, у нас есть следующая база данных, содержащая 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. исключить

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

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

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" : "baeldung.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

Файл GridFS API также довольно прост:

  • GetFileName – возвращает имя файла
  • getMetadata – получает метаданные для данного файла
  • containsField – определяет, содержит ли документ поле с заданным именем
  • get – получает поле из объекта по имени
  • getId – возвращает идентификатор объекта файла
  • keySet – возвращает имена полей объекта

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

В этой статье мы рассмотрели функции GridFS MongoDB и то, как взаимодействовать с ними с помощью Spring Data MongoDB.

Реализацию всех этих примеров и фрагментов кода можно найти в моем проекте github .