Mongoose で途中から field に default 定義を追加する場合の実装方針をご紹介します。
var mongoose = require('mongoose');
var orderSchema = new mongoose.Schema({
// 合計金額
amount: {
type: Number
},
// 送料無料の条件が適用される閾値 (単位: USD)
freeShippingThreshold: {
type: Number,
default: 100
}
});
var Order = mongoose.model('Order', orderSchema);
/**
* Case1: 新規 instance
* instance 化されたときはデフォルト値が入った状態で便利
**/
var order = new Order();
/**
* order : {
* _id: 5512abca1c6bb890a82b0951,
* freeShippingThreshold: 100
* }
**/
/**
* Case2: MongoDB に保存されている既存データから取得した instance
*
* MongoDB に保存されているデータは下記の通り
*
* order : {
* _id: 50169294b1b4a1c21e00001e,
* amount: 150
* }
**/
Order.findOne(function (err, order) {
/**
* Mongoose の findOne method で instance 取得したときは、
* 値が入ってなければ default に設定した値がセットされる
*
* order : {
* _id: 50169294b1b4a1c21e00001e,
* amount: 150,
* freeShippingThreshold: 100
* }
**/
});
Case1 の新規インスタンスを作成するケースは、デフォルトで freeShippingThreshold に 100 が入ってるので、使い回しが便利です。何の問題もなさそうですね。
Case2 は既に MongoDB に保存されているが freeShippingThreshold に値が入ってないので、 100 が入った状態で order インスタンスを取得できます。しかし、この order が保存されたときはキャンペーン期間中で送料無料の閾値が $50 になっていたので 50 が入ったデータが欲しいわけです。こういうケースは後から default: 100 を設定するタイミングで既存データに適切な freeShippingThreshold を設定してあげる必要があるわけです。
以上、うっかりしてると陥るかもしれない Mongoose の運用事例を現場からお送りしました。