1. 概要

このチュートリアルでは、 Spring Data MongoDBのコア機能:との対話 GridFS。

GridFSストレージ仕様は、主にBSON-ドキュメントサイズの制限である16MBを超えるファイルを処理するために使用されます。 また、Spring Dataは、このファイルシステムと簡単に対話できるように、 GridFsOperationsインターフェイスとその実装– GridFsTemplate –を提供します。

2. 構成

2.1. XML構成

GridFsTemplateの単純なXML構成から始めましょう。

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

GridFsTemplate へのコンストラクター引数には、Mongoデータベースを作成する mongoDbFactory へのBean参照と、JavaタイプとMongoDBタイプの間で変換するmongoConverterが含まれます。 それらのBeanの定義は以下のとおりです。

<mongo:db-factory id="mongoDbFactory" dbname="test" mongo-client-ref="mongoClient" />

<mongo:mapping-converter id="mongoConverter" base-package="com.baeldung.converter">
    <mongo:custom-converters base-package="com.baeldung.converter"/>
</mongo:mapping-converter>

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()メソッドを使用し、親クラスAbstractMongoClientConfigurationで定義されたMappingMongoConverterを自動配線しました。

3. GridFsTemplateコアメソッド

3.1. ストア

store メソッドは、ファイルをMongoDBに保存します。

空のデータベースがあり、そのデータベースにファイルを保存したいとします。

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

DBObjectstoreメソッドに渡すことで、ファイルとともに追加のメタデータを保存できることに注意してください。 この例では、DBObjectは次のようになります。

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

GridFS は、2つのコレクションを使用して、ファイルのメタデータとそのコンテンツを保存します。 ファイルのメタデータはファイルコレクションに保存され、ファイルのコンテンツはチャンクコレクションに保存されます。 どちらのコレクションにも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 は、指定されたクエリ条件を満たすドキュメントを1つだけ返します。

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

上記のコードは、上記の例で追加された結果レコードを返します。 データベースにクエリに一致する複数のレコードが含まれている場合、データベースは1つのドキュメントのみを返します。 返される特定のレコードは、自然な順序(ドキュメントがデータベースに保存された順序)に従って選択されます。

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<GridFSFile> fileList = new ArrayList<GridFSFile>();
gridFsTemplate.find(new Query()).into(fileList);

基準を指定しなかったため、結果のリストには2つのレコードが含まれているはずです。

もちろん、findメソッドのいくつかの基準を提供することもできます。 たとえば、メタデータに alex という名前のユーザーが含まれているファイルを取得する場合、コードは次のようになります。

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

結果のリストには、1つのレコードのみが含まれます。

3.4. 削除

delete は、コレクションからドキュメントを削除します。

前の例のデータベースを使用して、次のコードがあるとします。

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

delete を実行した後、データベースに残るレコードは1つだけです。

{
    "_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」で始まる2つのレコードが返されます(この場合、両方とも test.png という名前が付けられています)。

4. GridFSFileコアメソッド

GridFSFileAPIも非常にシンプルです。

  • getFilename –ファイルのファイル名を取得します
  • getMetaData –指定されたファイルのメタデータを取得します
  • containsField –ドキュメントに指定された名前のフィールドが含まれているかどうかを判別します
  • get –オブジェクトから名前でフィールドを取得します
  • getId –ファイルのオブジェクトIDを取得します
  • keySet –オブジェクトのフィールド名を取得します

5. 結論

この記事では、MongoDBの GridFS 機能と、SpringDataMongoDBを使用してそれらを操作する方法について説明しました。

これらすべての例とコードスニペットの実装は、 mygithubプロジェクトにあります。