[Mongoose] Implementation Strategy for Adding Default Field Definitions Midway

Tadashi Shigeoka ·  Wed, March 25, 2015

I’ll introduce an implementation strategy for adding default field definitions midway in Mongoose.

mongoose

var mongoose = require('mongoose');

var orderSchema = new mongoose.Schema({
  // Total amount
  amount: {
    type: Number
  },
  // Threshold for free shipping eligibility (Unit: USD)
  freeShippingThreshold: {
    type: Number,
    default: 100
  }
});

var Order = mongoose.model('Order', orderSchema);


/**
 * Case1: New instance
 * Convenient that default values are set when instantiated
 **/
var order = new Order();
/**
 * order : {
 *    _id: 5512abca1c6bb890a82b0951,
 *    freeShippingThreshold: 100
 * }
 **/


/**
 * Case2: Instance retrieved from existing data stored in MongoDB
 *
 * Data stored in MongoDB is as follows:
 * 
 * order : {
 *   _id: 50169294b1b4a1c21e00001e,
 *   amount: 150
 * }
 **/
Order.findOne(function (err, order) {
  /**
   * When retrieving instance with Mongoose's findOne method,
   * if no value exists, the default value is set
   * 
   * order : {
   *   _id: 50169294b1b4a1c21e00001e,
   *   amount: 150,
   *   freeShippingThreshold: 100
   * }
   **/
});

Case 1 for creating new instances is convenient for reuse since freeShippingThreshold defaults to 100. No problems there.

Case 2 involves data already stored in MongoDB that doesn’t have a value for freeShippingThreshold, so you can retrieve the order instance with 100 filled in. However, when this order was saved, it was during a campaign period when the free shipping threshold was $50, so we actually want data with 50. In cases like this, when setting default: 100 later, we need to set appropriate freeShippingThreshold values for existing data.

That’s all from the Gemba - a Mongoose operational case study you might accidentally fall into if you’re not careful.