每个用户的个人猫鼬模式

Individual mongoose schema for each user

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

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

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

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

module.exports = function (userID) {
   Customer(userID) 
}

文件/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;

客户从两个不同的浏览器登录时出现问题,return错误: 编译后无法覆盖 123customer 模型。 我通过更改解决了问题:

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

至:

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

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

如果您真的想坚持为用户动态创建集合,比 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;

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

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

让我们定义一个模型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);
      }
    }
  }
}

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

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

models.customer.findOne(...);

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