GridFS Support

MongoDB 支持在其文件系统 GridFS 中存储二进制文件。Spring Data MongoDB 提供 GridFsOperationsReactiveGridFsOperations 接口以及相应的实现 GridFsTemplateReactiveGridFsTemplate,让你可以与文件系统进行交互。你可以通过将 MongoDatabaseFactory/ReactiveMongoDatabaseFactoryMongoConverter 交付给模板实例来设置模板实例,如下例所示:

MongoDB supports storing binary files inside its filesystem, GridFS. Spring Data MongoDB provides a GridFsOperations and ReactiveGridFsOperations interface as well as the corresponding implementation, GridFsTemplate and ReactiveGridFsTemplate, to let you interact with the filesystem. You can set up a template instance by handing it a MongoDatabaseFactory/ReactiveMongoDatabaseFactory as well as a MongoConverter, as the following example shows:

  • Imperative

  • Reactive

  • XML

class GridFsConfiguration extends AbstractMongoClientConfiguration {

  // … further configuration omitted

  @Bean
  public GridFsTemplate gridFsTemplate() {
    return new GridFsTemplate(mongoDbFactory(), mappingMongoConverter());
  }
}
class ReactiveGridFsConfiguration extends AbstractReactiveMongoConfiguration {

  // … further configuration omitted

  @Bean
  public ReactiveGridFsTemplate reactiveGridFsTemplate() {
    return new ReactiveGridFsTemplate(reactiveMongoDbFactory(), mappingMongoConverter());
  }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/data/mongo
https://www.springframework.org/schema/data/mongo/spring-mongo.xsd
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">

  <mongo:db-factory id="mongoDbFactory" dbname="database" />
  <mongo:mapping-converter id="converter" />

  <bean class="org.springframework.data.mongodb.gridfs.GridFsTemplate">
    <constructor-arg ref="mongoDbFactory" />
    <constructor-arg ref="converter" />
  </bean>

</beans>

现在可以注入并使用该模板来执行存储和检索操作,如下例所示:

The template can now be injected and used to perform storage and retrieval operations, as the following example shows:

Using GridFS to store files
  • Imperative

class GridFsClient {

  @Autowired
  GridFsOperations operations;

  @Test
  public void storeFileToGridFs() {

    FileMetadata metadata = new FileMetadata();
    // populate metadata
    Resource file = … // lookup File or Resource

    operations.store(file.getInputStream(), "filename.txt", metadata);
  }
}

store(…) 操作将获取一个 InputStream、一个文件名以及(可选)要存储的文件的元数据信息。该元数据可以是 MongoConverter 将编组的任意对象,该对象使用 GridFsTemplate 配置。或者,你也可以提供 Document

The store(…) operations take an InputStream, a filename, and (optionally) metadata information about the file to store. The metadata can be an arbitrary object, which will be marshaled by the MongoConverter configured with the GridFsTemplate. Alternatively, you can also provide a Document.

Reactive
class ReactiveGridFsClient {

  @Autowired
  ReactiveGridFsTemplate operations;

  @Test
  public Mono<ObjectId> storeFileToGridFs() {

    FileMetadata metadata = new FileMetadata();
    // populate metadata
    Publisher<DataBuffer> file = … // lookup File or Resource

    return operations.store(file, "filename.txt", metadata);
  }
}

store(…) 操作将获取一个 Publisher<DataBuffer>、一个文件名以及(可选)要存储的文件的元数据信息。该元数据可以是 MongoConverter 将编组的任意对象,该对象使用 ReactiveGridFsTemplate 配置。或者,你也可以提供 Document

The store(…) operations take an Publisher<DataBuffer>, a filename, and (optionally) metadata information about the file to store. The metadata can be an arbitrary object, which will be marshaled by the MongoConverter configured with the ReactiveGridFsTemplate. Alternatively, you can also provide a Document.

MongoDB 的驱动程序使用 AsyncInputStreamAsyncOutputStream 接口交换二进制流。Spring Data MongoDB 将这些接口调整为 Publisher<DataBuffer>。在 Spring’s reference documentation 中阅读有关 DataBuffer 的更多信息。

The MongoDB’s driver uses AsyncInputStream and AsyncOutputStream interfaces to exchange binary streams. Spring Data MongoDB adapts these interfaces to Publisher<DataBuffer>. Read more about DataBuffer in Spring’s reference documentation.

你可以通过 find(…)getResources(…) 方法从文件系统读取文件。让我们先看一下 find(…) 方法。你可以找到单个文件或匹配 Query 的多个文件。你可以使用 GridFsCriteria 帮助程序类来定义查询。它提供静态工厂方法来封装默认元数据字段(如 whereFilename()whereContentType())或通过 whereMetaData() 自定义字段。以下示例展示如何使用模板查询文件:

You can read files from the filesystem through either the find(…) or the getResources(…) methods. Let’s have a look at the find(…) methods first. You can either find a single file or multiple files that match a Query. You can use the GridFsCriteria helper class to define queries. It provides static factory methods to encapsulate default metadata fields (such as whereFilename() and whereContentType()) or a custom one through whereMetaData(). The following example shows how to use the template to query for files:

Using GridFsTemplate to query for files
  • Imperative

  • Reactive

class GridFsClient {

  @Autowired
  GridFsOperations operations;

  @Test
  public void findFilesInGridFs() {
    GridFSFindIterable result = operations.find(query(whereFilename().is("filename.txt")));
  }
}
class ReactiveGridFsClient {

  @Autowired
  ReactiveGridFsTemplate operations;

  @Test
  public Flux<GridFSFile> findFilesInGridFs() {
    return operations.find(query(whereFilename().is("filename.txt")))
  }
}

目前,MongoDB 不支持在从 GridFS 检索文件时定义排序条件。因此,传递给 find(…) 方法的 Query 实例上定义的任何排序条件都会被忽略。

Currently, MongoDB does not support defining sort criteria when retrieving files from GridFS. For this reason, any sort criteria defined on the Query instance handed into the find(…) method are disregarded.

从 GridFs 读取文件的另一个选项是使用 ResourcePatternResolver 接口引入的方法。它们允许将 Ant 路径传递到方法中,因此可以检索与给定模式匹配的文件。以下示例演示如何使用 GridFsTemplate 读取文件:

The other option to read files from the GridFs is to use the methods introduced by the ResourcePatternResolver interface. They allow handing an Ant path into the method and can thus retrieve files matching the given pattern. The following example shows how to use GridFsTemplate to read files:

Using GridFsTemplate to read files
  • Imperative

  • Reactive

class GridFsClient {

  @Autowired
  GridFsOperations operations;

  public GridFsResources[] readFilesFromGridFs() {
     return operations.getResources("*.txt");
  }
}
class ReactiveGridFsClient {

  @Autowired
  ReactiveGridFsOperations operations;

  public Flux<ReactiveGridFsResource> readFilesFromGridFs() {
     return operations.getResources("*.txt");
  }
}

GridFsOperations 扩展了 ResourcePatternResolver 并允许 GridFsTemplate(例如)插入到 ApplicationContext 中,以从 MongoDB 数据库读取 Spring 配置文件。

GridFsOperations extends ResourcePatternResolver and lets the GridFsTemplate (for example) to be plugged into an ApplicationContext to read Spring Config files from MongoDB database.

默认情况下,GridFsTemplate 在首次 GridFS 交互时获得 GridFSBucket 一次。之后,模板实例会重复使用缓存的 bucket。要从同一模板实例使用不同的 bucket,请使用接受 Supplier<GridFSBucket> 的构造函数。

By default, GridFsTemplate obtains GridFSBucket once upon the first GridFS interaction. After that, the template instance reuses the cached bucket. To use different buckets, from the same Template instance use the constructor accepting Supplier<GridFSBucket>.