【问题标题】:Mongoose multitenancy - handling document references + populateMongoose 多租户 - 处理文档引用 + 填充
【发布时间】:2014-02-22 02:27:11
【问题描述】:

我读过很多关于 Mongoose/MongoDB 中的多租户设置选项的文章。选项有:

  1. 单独的数据库。这是一个禁忌,因为每个数据库实例都有开销
  2. 同一数据库中的前缀集合 - 我将拥有共享相同架构的 tenant1_Productstenant2_Products
  3. 引用回tenant 文档的标准集合。

#2 似乎是扩展的最佳选择,因为它允许通过前缀轻松进行分片。所以,假设,我会实现这样的东西来动态检索某个租户的模型:

tenant.methods.getModel = function(name) {
    return mongoose.model(this.uniqid + '_' + name);
}

假设我使用正确的架构提前为所有租户注册了所有模型,那么我可以执行var productModel = myTenant.getModel('Product');,然后从那里创建/更新。

问题在于,当您需要实现文档引用以使用 Mongoose 的 populate 方法时。例如,

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) {
    ...
});    

基本上为此,您需要将ref 属性设为动态(即一个函数),该属性根据定义当前租户的某个变量返回不同的集合名称,或者您可以将其保持为静态但找到某种方式告诉populate 方法自动添加适当的前缀。

实现这一目标的最佳方法是什么?或者,使用上面的选项#3 来避免这些问题是否更有意义?如果是这样,这对分片/缩放方法有影响吗?

【问题讨论】:

  • 我喜欢函数tenant() + 名称的简单性。但是,这将取决于最终会创建多少集合?
  • 好吧,如果我要使用 ref=function() 路由,我必须添加该功能并发送拉取请求。另一种选择是在我为租户注册它们时修改每个模式中的ref 属性。问题是,如果我们有数百个租户,每个租户定义 15 个模式会导致内存问题吗?我想这将是一个很好的问题。
  • 一个拉取请求,为了什么? ref: tenant() + 'Category?
  • 这不算太多。以下是需要考虑的事项:docs.mongodb.org/manual/core/data-model-operations/…
  • @WiredPrairie tenant() 将在定义架构时立即执行,而不是在每次使用架构时执行。我需要它在每个请求本质上是动态的,因为请求数据决定了它是哪个租户。

标签: node.js mongodb mongoose multi-tenant


【解决方案1】:

对于任何对此感兴趣的人,我继续创建了一个包来处理所有这些,因为我找不到现有的包。

https://www.npmjs.org/package/mongoose-multitenant

它为每个租户使用单独的集合并根据需要编译架构,可选择修改相关文档的ref 属性以将其保留在租户内。

【讨论】:

  • 由于我的用例需要额外的安全性,单独的集合是不够的,我不得不使用单独的数据库,从连接的角度来看,这更难管理。
猜你喜欢
  • 2019-01-08
  • 2013-07-08
  • 2014-08-06
  • 2017-01-27
  • 1970-01-01
  • 1970-01-01
  • 2014-08-16
  • 2019-05-26
  • 1970-01-01
相关资源
最近更新 更多