My CMS написан на Node.js + Express + Mongoose. Это многопользовательская CMS, и каждый сайт имеет свою собственную базу данных. Поэтому мне нужно было заставить Mongoose переключать соединение при каждом HTTP-запросе. Я посмотрел на какое-то решение или на кого-то, у кого было такое же состояние, но безуспешно. Так что это мое решение:Mongoose динамические модели, не могут использовать populate()
HTTP Request:
router.get('/site/pages', function (req, res) {
pagesBiz.list(req.session, function(err, list) {
//do stuff
});
});
БИЗ компонент (pagesBiz):
module.exports = {
list: function(session, callback) {
Page(session.database).find(callback);
}
}
Модель (Page)
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);
}
Итак, как это работает? Когда пользователь регистрируется в новом пользовательском сеансе, создается и привязывается к пользователю через куки-файл сеанса (я использую сеанс MongoStore + Express). Сеанс содержит имя базы данных, которое используется для динамического создания моделей Mongoose.
Он отлично работает, пользователи разных сайтов читают из своих собственных баз данных, не рискуя «столкновениями», с другой стороны мне приходится передавать сеанс (или имя базы данных) вокруг функций, но я предполагаю, что это как Node.js работает в многопоточном контексте.
Единственная проблема, когда я использую метод заселить(), я получаю эту ошибку:
f:\www\rudsjs\node_modules\mongoose\lib\connection.js:625 throw new MongooseError.MissingSchemaError(name); ^MissingSchemaError: Schema hasn't been registered for model "User". Use mongoose.model(name, schema) at NativeConnection.Connection.model (f:\www\rudsjs\node_modules\mongoose\lib\connection.js:625:11) at populate (f:\www\rudsjs\node_modules\mongoose\lib\model.js:2136:24) at Function.Model.populate (f:\www\rudsjs\node_modules\mongoose\lib\model.js:2101:5) at 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)
Process finished with exit code 8
Я попытался поджать модель перед вызовом Заселите() с помощью этого:
пользователя (session.database);
, но проблема, как представляется, связано с тем, как Mongoose кэширует модели (это не мое), я смотрел на connection.js
model = this.base.models[name];
if (!model) {
throw new MongooseError.MissingSchemaError(name);
}
так что я нужен способ, чтобы вставить мою модель внутри это.base.models. Есть ли у вас какие-либо идеи? У вас есть особенно лучшее решение для внедрения среды с несколькими сайтами/несколькими базами данных?