Spring Data MongoDBのGridFS

Spring Data MongoDBのGridFS

1. 概要

このチュートリアルでは、core features of Spring Data MongoDB: interacting with*GridFS*.の1つについて説明します。

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

2. 設定

2.1. XML構成

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


    
    

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




    

2.2. Java設定

Javaのみを使用して、同様の構成を作成しましょう。

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

この構成では、org.springframework.data.mongodb.config.AbstractMongoConfigurationからmongoDbFactoryおよびmappingMongoConverterを使用しました。

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();

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

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

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

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

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

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);

基準を提供しなかったため、結果のリストには2つのレコードが含まれます。

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

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

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

3.4. delete

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

4. GridFSFileコアメソッド

GridFSFileAPIも非常に単純です。

  • getFilename –ファイルのファイル名を取得します

  • getMetaData –指定されたファイルのメタデータを取得します

  • containsField –ドキュメントに指定された名前のフィールドが含まれているかどうかを判別します

  • get –名前でオブジェクトからフィールドを取得します

  • getId –ファイルのオブジェクトIDを取得します

  • keySet –オブジェクトのフィールド名を取得します

5. 結論

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

これらすべての例とコードスニペットcan be found inmy github projectの実装–これはEclipseベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。