title: Mongoose multitenancy - handling document references + populate
body: <p>I've read a bunch about multitenancy setup options in Mongoose/MongoDB. The options are:</p>
  
  <ol>
  <li>Separate databases. This is a no-no because of the overhead per database instance</li>
  <li>Prefixed collections in the same database - I would have <code>tenant1_Products</code> and <code>tenant2_Products</code> which share the same schema.</li>
  <li>Standard collections with a reference back to the <code>tenant</code> document.</li>
  </ol>
  
  <p>It seems to be that #2 is the best option for scaling, since it allows for easy sharding by prefix. So, assuming that, I would implement something like this to dynamically retrieve the model for a certain tenant:</p>
  
  <pre><code>tenant.methods.getModel = function(name) {
      return mongoose.model(this.uniqid + '_' + name);
  }
  </code></pre>
  
  <p>Assuming I register all models for all tenants ahead of time with the correct schema, then I could do <code>var productModel = myTenant.getModel('Product');</code>, and then create/update from there.</p>
  
  <p>The problem with this is when you need to implement document references to make use of Mongoose's <code>populate</code> method. E.g.,</p>
  
  <pre><code>var productSchema = new mongoose.Schema({
      name:String,
      categories:[
          {
              type:mongoose.Schema.Types.ObjectId,
              // This will need to change to "tenant1_Category", etc
              ref:'Category'
          }
      ]
  });
  mongoose.model('tenant1_Product', productSchema);
  tenant1.getModel('Product').find().populate('categories').exec(function(err, results) {
      ...
  });    
  </code></pre>
  
  <p>Essentially for this you'd need either need to make the <code>ref</code> property dynamic (IE, a function) that returns a different collection name depending upon some variable that defines the current tenant, or you could keep it static but find some way of telling the <code>populate</code> method to automatically add the appropriate prefix.</p>
  
  <p>What is the best way of accomplishing this? Or, does it make more sense to go with option #3 above to avoid these issues? If so, does that have an effect on sharding/scaling methods?</p>