[Mongoose] stream を使ってバッチ処理するときは noCursorTimeout: true オプションを設定すると幸せになれるかも

Express.js(Node.js) + Mongoose(MongoDB) という構成で、バッチ処理を長時間実行すると途中で終了してしまう問題が発生しました。

mongoose | マングース

状況としては、まだ cursor が次のデータを取得できるはずなのに、stream.on ‘data’ 内では次のデータが渡ってこなくて、stream.on ‘error’ が呼ばれることなく、stream.on ‘close’ が呼ばれている感じです。cursor がタイムアウトしてしまっているのが原因らしいです。

解決方法としては、第三引数に noCursorTimeout: true を指定することで、途中で終了せずにバッチ処理を最後まで実行することができました。

var stream = User.find(
  {},
  {},
  { noCursorTimeout: true }
).stream();
 
stream.on('data', function (doc) {
  // do something with the mongoose document
}).on('error', function (err) {
  // handle the error
}).on('close', function () {
  // the stream is closed
});

参考情報