我有一个与多个客户打交道的Node.js项目。由于几个原因,主要是关注点分离,安全性和部分可转移性,我必须将每个客户的数据放入一个单独的Mongo数据库中。所有数据库都存储相同的对象类型,因此具有相同的具有相同结构的集合集。我已经找到了解决该问题的许多技术解决方案,但是我的问题更多地是与处理这种情况的最佳实践有关。我的代码的简化视图(省略了样板代码以创建服务器,模块结构等):
const mongoose = require('mongoose');
// Customer codes act as DB names, actually comes from config file or DB
let customers = ['c1', 'c2'];
// keeps all mongoose connections
let conns = {};
// create a connection(pool) for each DB
for (let i in customers) {
let dbname = customers[i];
conns[dbname] = mongoose.createConnection(`mongodb://${host}:${port}/${dbname}`);
}
// a simple Schema for blog articles
const ArticleSchema = new mongoose.Schema({
title: String,
text: String
});
// keeps all Article models
let Article = {};
// create the identical models for the different DBs
// remember: the dbname is the unique customer's code
for (let dbname in conns) {
let conn = conns[dbname];
Article[dbname] = conn.model('Article', ArticleSchema);
}
const app = require('express');
// returns all articles of a certain customer
app.get('/customers/:customerid/articles', function(req, res) {
// get the customer's code from the URL
let dbname = req.params.customerid;
// Query the database
Article[dbname].find({}, function(err, articles) {
if (err) return res.status(500).send('DB error');
res.status(200).send(articles);
});
});
此代码有效。尽管如此,我想知道是否存在最佳实践,我不知道如何处理这种要求。特别是,将连接和模型保留在地图中,并使用dbname放在方括号中访问对象,这感觉很奇怪。请记住,这是一个极其简化的版本。在实际版本中,代码分布在处理不同对象类型等的多个模块中。
注意:一个简单的mongoose.connection.useDb(dbName)
切换到另一个数据库是行不通的,因为必须针对该连接注册该模型,该连接本身必须绑定到数据库(据我了解) )。
更新:按照Paul提到的问题中的建议,处理具有单个节点流程的每个客户并针对该客户设置向这些流程的代理切换目前不可行在当前环境中进行必要的行政管理工作。我们必须立即启动该服务。