单个 node.js 项目中的 Mongoose 和多个数据库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19474712/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mongoose and multiple database in single node.js project
提问by pupot
I'm doing a Node.js project that contains sub projects. One sub project will have one Mongodb database and Mongoose will be use for wrapping and querying db. But the problem is
我正在做一个包含子项目的 Node.js 项目。一个子项目将有一个 Mongodb 数据库,Mongoose 将用于包装和查询数据库。但问题是
- Mongoose doesn't allow to use multiple databases in single mongoose instance as the models are build on one connection.
To use multiple mongoose instances, Node.js doesn't allow multiple module instances as it has caching system in
require(). I know disable module caching in Node.js but I think it is not the good solution as it is only need for mongoose.I've tried to use
createConnection()andopenSet()in mongoose, but it was not the solution.I've tried to deep copy the mongoose instance (http://blog.imaginea.com/deep-copy-in-javascript/) to pass new mongoose instances to the sub project, but it throwing
RangeError: Maximum call stack size exceeded.
- Mongoose 不允许在单个 mongoose 实例中使用多个数据库,因为模型是建立在一个连接上的。
要使用多个 mongoose 实例,Node.js 不允许多个模块实例,因为它在
require(). 我知道在 Node.js 中禁用模块缓存,但我认为这不是一个好的解决方案,因为它只需要 mongoose。我试过在猫鼬中使用
createConnection()和openSet(),但这不是解决方案。我试图深度复制 mongoose 实例(http://blog.imaginea.com/deep-copy-in-javascript/)以将新的 mongoose 实例传递给子项目,但它抛出
RangeError: Maximum call stack size exceeded.
I want to know is there anyways to use multiple database with mongoose or any workaround for this problem? Because I think mongoose is quite easy and fast. Or any other modules as recommendations?
我想知道是否可以使用带有 mongoose 的多个数据库或解决此问题的任何解决方法?因为我认为猫鼬非常容易和快速。或者任何其他模块作为推荐?
采纳答案by yemaw
One thing you can do is, you might have subfolders for each projects. So, install mongoose in that subfolders and require() mongoose from own folders in each sub applications. Not from the project root or from global. So one sub project, one mongoose installation and one mongoose instance.
您可以做的一件事是,您可能为每个项目都有子文件夹。因此,请在该子文件夹中安装 mongoose,并在每个子应用程序中从自己的文件夹中安装 require() mongoose。不是来自项目根目录或全局。所以一个子项目,一个 mongoose 安装和一个 mongoose 实例。
-app_root/
--foo_app/
---db_access.js
---foo_db_connect.js
---node_modules/
----mongoose/
--bar_app/
---db_access.js
---bar_db_connect.js
---node_modules/
----mongoose/
In foo_db_connect.js
在 foo_db_connect.js 中
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/foo_db');
module.exports = exports = mongoose;
In bar_db_connect.js
在 bar_db_connect.js 中
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/bar_db');
module.exports = exports = mongoose;
In db_access.js files
在 db_access.js 文件中
var mongoose = require("./foo_db_connect.js"); // bar_db_connect.js for bar app
Now, you can access multiple databases with mongoose.
现在,您可以使用 mongoose 访问多个数据库。
回答by robertklep
According to the fine manual, createConnection()canbe used to connect to multiple databases.
根据fine manual,createConnection()可以用来连接多个数据库。
However, you need to create separate models for each connection/database:
但是,您需要为每个连接/数据库创建单独的模型:
var conn = mongoose.createConnection('mongodb://localhost/testA');
var conn2 = mongoose.createConnection('mongodb://localhost/testB');
// stored in 'testA' database
var ModelA = conn.model('Model', new mongoose.Schema({
title : { type : String, default : 'model in testA database' }
}));
// stored in 'testB' database
var ModelB = conn2.model('Model', new mongoose.Schema({
title : { type : String, default : 'model in testB database' }
}));
I'm pretty sure that you can share the schema between them, but you have to check to make sure.
我很确定您可以在它们之间共享架构,但您必须检查以确保。
回答by Tahnik Mustasin
Pretty late but this might help someone. The current answers assumes you are using the same file for your connections and models.
很晚了,但这可能会对某人有所帮助。当前答案假定您对连接和模型使用相同的文件。
In real life, there is a high chance that you are splitting your models into different files. You can use something like this in your main file:
在现实生活中,您很有可能将模型拆分为不同的文件。您可以在主文件中使用类似的内容:
mongoose.connect('mongodb://localhost/default');
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => {
console.log('connected');
});
which is just how it is described in the docs. And then in your model files, do something like the following:
这就是文档中的描述方式。然后在您的模型文件中,执行以下操作:
import mongoose, { Schema } from 'mongoose';
const userInfoSchema = new Schema({
createdAt: {
type: Date,
required: true,
default: new Date(),
},
// ...other fields
});
const myDB = mongoose.connection.useDb('myDB');
const UserInfo = myDB.model('userInfo', userInfoSchema);
export default UserInfo;
Where myDB is your database name.
其中 myDB 是您的数据库名称。
回答by Eric
As an alternative approach, Mongoose does export a constructor for a new instance on the default instance. So something like this is possible.
作为替代方法,Mongoose 确实为默认实例上的新实例导出了一个构造函数。所以这样的事情是可能的。
var Mongoose = require('mongoose').Mongoose;
var instance1 = new Mongoose();
instance1.connect('foo');
var instance2 = new Mongoose();
instance2.connect('bar');
This is very useful when working with separate data sources, and also when you want to have a separate database context for each user or request. You will need to be careful, as it is possible to create a LOT of connections when doing this. Make sure to call disconnect() when instances are not needed, and also to limit the pool size created by each instance.
这在处理单独的数据源时非常有用,而且当您希望为每个用户或请求拥有单独的数据库上下文时也是如此。您需要小心,因为这样做可能会创建很多连接。确保在不需要实例时调用 disconnect() ,并限制每个实例创建的池大小。
回答by PKInd007
A bit optimized(for me atleast) solution.write this to a file db.js and require this to wherever required and call it with a function call and you are good to go.
有点优化(至少对我而言)解决方案。将其写入文件 db.js 并将其要求到任何需要的地方并使用函数调用调用它,您就可以开始了。
const MongoClient = require('mongodb').MongoClient;
async function getConnections(url,db){
return new Promise((resolve,reject)=>{
MongoClient.connect(url, { useUnifiedTopology: true },function(err, client) {
if(err) { console.error(err)
resolve(false);
}
else{
resolve(client.db(db));
}
})
});
}
module.exports = async function(){
let dbs = [];
dbs['db1'] = await getConnections('mongodb://localhost:27017/','db1');
dbs['db2'] = await getConnections('mongodb://localhost:27017/','db2');
return dbs;
};

