Mongoose の Document インスタンスにプロパティを追加しての JSON 化

Node.js + Express + Mongoose で MongoDB から取得した Document インスタンスにいくつかのプロパティを追加して JSON で返す Web API を作っていたんですが、プロパティを追加した Document インスタンスをそのまま res.send で送っても追加したプロパティが JSON に含まれません。書いていたコードはこんな感じ。

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');

var Doc = new Schema({
  title: String,
  body: String
});

mongoose.model('Doc', Doc);

...

app.get('/api/docs', function(req, res) {
  mongoose.model('Doc').find({}, function(err, docs) {
    docs.forEach(function(d) { d.comment = 'hoge'; });
    res.send(docs);
  });
});

調べてみると、(そもそも Document に値を追加するには setValue を使うようだったんですけど、)どうも Document には toJSON が実装されているみたいで、そこでは純粋な MongoDB のドキュメントの部分だけを JSON にするようになっているようです。

で、今回の場合だと色々方法はあるとは思いますが、toObject で取得したドキュメントにプロパティを追加して返すのが良さそうだったので、下記のように書き換えて無事成功。

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');

var Doc = new Schema({
  title: String,
  body: String
});

mongoose.model('Doc', Doc);

...

app.get('/api/docs', function(req, res) {
  mongoose.model('Doc').find({}, function(err, docs) {
    res.send(docs.map(function(d) {
      var obj = d.toObject();
      obj.comment = 'hoge';
      return obj;
    }));
  });
});