LoginSignup
8
8

More than 5 years have passed since last update.

MongoDBの新しいGridFS APIを使ってみる

Last updated at Posted at 2016-06-24

ことのはじまり

MongoDBにはGridFSというファイルを他のメタデータつきでまるっと格納できる機能があり、コマンドラインからもプログラムからもデータを突っ込めるというのでかなり便利に使っています

これまでNode.js上でMongooseで手軽にMongoDBのデータを出し入れしながらAPIが若干違うGridFSもエレガントに使おうという場合はgridfs-streamと組み合わせるのが定跡のように言われておりました

しかし先日昔の作りかけアプリをES6ベースな書き方になおしたい→node.jsとnpmモジュール関連を一気にバージョンアップしたところコケるアプリがチラホラとありまして
エラーメッセージを見るとアプリ本体やMongoose周りは別段問題はなさそうだったのですが、gridfs-stream関連を使っているあたりで色々出てる感じでした

調べてみるとgridfs-streamで使っているGridStore APIが最近のMongoDB Native Driverでは

The GridStore API is deprecated

どうやらGrid File System APIに移行しなさいと言っているようで

件のコケたアプリのエラーはこれだけが原因というわけでもなかったのですが、見かけたついでなので new GridFS API なるものがどんなものなのか試してみました

Grid File System API

ドキュメントを読むとNode.jsのstreams3にも対応したstreamベースのAPIらしく、今までgridfs-streamを経由してやっていたことをネイティブドライバのモジュールが素でやってくれそうな雰囲気

というわけでMongooseとの組み合わせでデータを出し入れするサンプルを書いてみました

model.js
var Mongoose = require('mongoose');
var ObjectId = Mongoose.Types.ObjectId;
var mongoose = Mongoose.connect('mongodb://localhost/something');

var Schema = {};
var Model = {};

Schema.File = new Mongoose.Schema({
    filename: {type: String},
    contentType: {type: String},
    length: {type: Number},
    md5: {type: String},
    uploadDate: {type: Date},
    metadata: Mongoose.Schema.Types.Mixed
}, {strict: false});

Schema.File.statics.writeStream = function(filename, options){
    var bucket = new Mongoose.mongo.GridFSBucket(mongoose.connection.db);
    return bucket.openUploadStream(filename, options);
};

Schema.File.methods.readStream = function(callback){
    var bucket = new Mongoose.mongo.GridFSBucket(mongoose.connection.db);
    return bucket.openDownloadStream(this._id);
};

Schema.File.methods.unlink = function(callback){
    var bucket = new Mongoose.mongo.GridFSBucket(mongoose.connection.db);
    bucket.delete(this._id, function(err){
        callback(err);
    });
};
Model.File = Mongoose.model('File', Schema.File, 'fs.files');

module.exports = Model;

writer.js
var fs = require('fs');
var Model = require('model.js');
var readstream = fs.createReadStream('example.txt');
var writestream = Model.File.writeStream('example.txt', {
    metadata: {}
});
writestream.once('finish', function(){
    console.info('オワタ');
});

readstream.pipe(writestream);
8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8