我的CMS是用Node.js + Express + Mongoose编写的。它是一个多站点CMS,每个站点都有自己的数据库。所以我需要让Mongoose在每个HTTP请求时切换连接。我四处寻找解决方案,或者有同样情况的人,但没有成功。所以这是我的解决方案:
HTTP请求:
router.get('/site/pages', function (req, res) {
pagesBiz.list(req.session, function(err, list) {
//do stuff
});
});
BIZ组件(pagesBiz):
module.exports = {
list: function(session, callback) {
Page(session.database).find(callback);
}
}
型号(页面)
var cached = {};
var getModel = function (database) {
if(! cached[database]) {
var conn = mongoose.createConnection('mongodb://localhost/' + database);
cached[database] = conn.model('Page', pageSchema);
}
return cached[database];
}
module.exports = function(database) {
return getModel(database);
}
那它是如何运作的?当用户登录时,会创建新的用户会话并通过会话cookie绑定到用户(我使用MongoStore + Express Session)。会话包含用于动态实例化Mongoose模型的数据库的名称。
它完美地运行,不同站点的用户从他们自己的数据库中读取而没有"冲突"的风险,另一方面我必须在函数周围传递会话(或数据库名称),但是我想这就是Node.js在多线程上下文中的工作方式。
唯一的问题是当我使用populate方法()时,我收到此错误:
F:\ WWW \ rudsjs \ node_modules \猫鼬\ lib中\ connection.js:625 抛出新的MongooseError.MissingSchemaError(name); ^ MissingSchemaError:尚未为模型"用户"注册架构。使用mongoose.model(名称,架构) 在NativeConnection.Connection.model(f:\ www \ rudsjs \ node_modules \ mongoose \ lib \ connection.js:625:11) 在populate(f:\ www \ rudsjs \ node_modules \ mongoose \ lib \ model.js:2136:24) 在Function.Model.populate(f:\ www \ rudsjs \ node_modules \ mongoose \ lib \ model.js:2101:5) 在Object.cb(f:\ www \ rudsjs \ node_modules \ mongoose \ lib \ query.js:1159:16) at Object._onImmediate(f:\ www \ rudsjs \ node_modules \ mongoose \ node_modules \ mquery \ lib \ utils.js:137:16) at processImmediate [as _immediateCallback](timers.js:336:15)
使用退出代码8完成流程
我尝试使用以下方法在populate()调用之前预加载模型:
用户(session.database);
但问题似乎与Mongoose缓存模型的方式有关(不是我的),我看了connection.js
model = this.base.models[name];
if (!model) {
throw new MongooseError.MissingSchemaError(name);
}
所以我需要一种方法在 this.base.models 中插入我的模型。你有什么主意吗?您是否特别有更好的解决方案来实现多站点/多数据库环境?
答案 0 :(得分:0)
我找到了解决方案。我正在缓存模型而不是连接,因此我为每个模型生成了一个新的Mongoose连接,这就是为什么Mongoose无法使用populate()加载其他模型的原因。
我的解决方案是:使用一个全局Cache对象来存储将用于构建所有模型的连接。
缓存全局对象
module.exports = {
Cache: {
database: {}
}
}
型号(页面)
module.exports = function(session) {
if(! Cache.database[session.database]) {
debug("Create connection to " + session.database);
var conn = mongoose.createConnection('mongodb://localhost/' + session.database);
Cache.database[session.database] = conn;
}
debug("[rud] " + session.database + " model created");
return Cache.database[session.database].model('Page', pageSchema);
}
如您所见,现在所有模型将共享存储在 Cache.database [session.database]
中的相同连接