2

我是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;

当客户从两个不同的浏览器登录并返回错误时会出现问题: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');
}

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

4

1 回答 1

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;

我希望您为每个用户动态创建集合的方法不会扩展,因为 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(...);

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

于 2016-01-19T09:10:24.033 回答