每个用户的单独猫鼬模式

Dan*_*man 2 mongoose node.js express mongoose-schema

我是 nodejs 的新手。我有一个带有 mongoose 和用户登录的应用程序。mongoDB 中的一些集合是针对所有用户的,而另一些则例如 customer-collection 是单独的,因此所有用户都有自己的客户集合。当用户登录并获取他的 jwt-token 时,各个猫鼬模型将被实例化:

var models = require('../models')(userID);
Run Code Online (Sandbox Code Playgroud)

在文件夹 /models 中有一个 index.js:

var Customer = require('./customermodel'); 

module.exports = function (userID) {
   Customer(userID) 
}
Run Code Online (Sandbox Code Playgroud)

文件/models/customermodel.js:

var mongooseCustomer = function(userID) {
    var schema = mongoose.Schema({
          _id: { type: Number},
          Name:  { type: String },
          Address:  { type: String },
        }, {collection: userID + 'userID'})
        return mongoose.model(userID + 'customer', schema);
}
Module.exports = mongooseCustomer;
Run Code Online (Sandbox Code Playgroud)

当客户从两个不同的浏览器登录并返回错误时会出现问题:无法覆盖123customer模型一旦编译。我通过改变解决了这个问题:

var models = require('../models')(userID);
Run Code Online (Sandbox Code Playgroud)

到:

try {
     var models = require('../models')(userID);
     console.log('Schema was created');
}
catch (err) {
     console.log('User is already logged in');
}
Run Code Online (Sandbox Code Playgroud)

现在我的问题是整个设置是否太复杂,是否有更干净的方法来处理以动态方式创建模型?

sai*_*ama 6

如果您真的想坚持为用户动态创建集合,try{ } catch(err)那么如果已经为用户编译了一个模型,那么比查询 mongoose更好的方法。该mongoose.model函数可用于定义检索模型:

var mongooseCustomer = function(userID) {
  var model = mongoose.model(userID + 'customer');

  if (!model) {
    var schema = mongoose.Schema({
      _id: { type: Number},
      Name:  { type: String },
      Address:  { type: String },
    }, {collection: userID + 'userID'});

    model = mongoose.model(userID + 'customer', schema);
  }

  return model;
};

Module.exports = mongooseCustomer;
Run Code Online (Sandbox Code Playgroud)

我希望您为每个用户动态创建集合的方法不会扩展,因为 mongoose 不是为处理第 1000 个模型而构建的,并且 Mongodb 具有与大多数数据库一样的最大集合限制。

恕我直言,更好的方法可能是在集合中使用鉴别器来识别租户并公开一个 db 层以透明的方式处理租户。

让我们定义一个暴露最小数据层的模型 node.js 模块

// First define the schema and model
var customerSchema = mongoose.Schema({
    _id: { type: Number},
    // Additional tenant discriminator
    userID: { type: Number, required: true }, 
    Name:  { type: String },
    Address:  { type: String },
  });

var customerModel = mongoose.model('customer', schema);

module.exports = function(userID) {
  return {
    customer: {
      find: function(query, callback) {
        query.userID = userID;
        customerModel.find(query, callback);
      },

      findOne: function(callback) {
        var query = { userID : userID };
        customerModel.findOne(query, callback);
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

使用这个最小层时,您确保用户 ID 始终添加到 Mongodb 函数中。

var models = require('../models')(123124432);

models.customer.findOne(...);
Run Code Online (Sandbox Code Playgroud)

您还可以使用 mongoose 中间件 ( http://mongoosejs.com/docs/middleware.html ) 以透明的方式处理多租户,而不是在 mongoose 之上定义您自己的数据层。