160

我正在做一个包含子项目的 Node.js 项目。一个子项目将有一个 Mongodb 数据库,Mongoose 将用于包装和查询数据库。但问题是

  • Mongoose 不允许在单个 mongoose 实例中使用多个数据库,因为模型是建立在一个连接上的。
  • 要使用多个 mongoose 实例,Node.js 不允许多个模块实例,因为它在require(). 我知道在 Node.js 中禁用模块缓存,但我认为这不是一个好的解决方案,因为它只需要猫鼬。

    我尝试在猫鼬中使用createConnection()and openSet(),但这不是解决方案。

    我试图深度复制 mongoose 实例(http://blog.imaginea.com/deep-copy-in-javascript/)以将新的 mongoose 实例传递给子项目,但它会抛出RangeError: Maximum call stack size exceeded.

我想知道无论如何使用多个数据库和猫鼬或任何解决这个问题的方法?因为我认为猫鼬非常容易和快速。或任何其他模块作为建议?

4

6 回答 6

248

根据细手册createConnection() 可以用来连接多个数据库。

但是,您需要为每个连接/数据库创建单独的模型:

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' }
}));

我很确定您可以在它们之间共享架构,但您必须检查以确保。

于 2013-10-20T08:15:52.720 回答
75

很晚了,但这可能会对某人有所帮助。当前答案假定您对连接和模型使用相同的文件。

在现实生活中,您很有可能将模型拆分为不同的文件。你可以在你的主文件中使用这样的东西:

mongoose.connect('mongodb://localhost/default');

const db = mongoose.connection;

db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => {
  console.log('connected');
});

这就是文档中描述的方式。然后在您的模型文件中,执行以下操作:

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;

其中 myDB 是您的数据库名称。

于 2018-06-12T13:24:51.573 回答
50

您可以做的一件事是,您可能有每个项目的子文件夹。因此,在该子文件夹中安装 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/

在 foo_db_connect.js

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/foo_db');
module.exports = exports = mongoose;

在 bar_db_connect.js

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/bar_db');
module.exports = exports = mongoose;

在 db_access.js 文件中

var mongoose = require("./foo_db_connect.js"); // bar_db_connect.js for bar app

现在,您可以使用 mongoose 访问多个数据库。

于 2013-10-20T08:14:09.823 回答
43

作为一种替代方法,Mongoose 确实为默认实例上的新实例导出构造函数。所以这样的事情是可能的。

var Mongoose = require('mongoose').Mongoose;

var instance1 = new Mongoose();
instance1.connect('foo');

var instance2 = new Mongoose();
instance2.connect('bar');

这在使用单独的数据源时非常有用,并且当您希望为每个用户或请求拥有单独的数据库上下文时也是如此。您需要小心,因为这样做时可能会创建很多连接。确保在不需要实例时调用 disconnect(),并限制每个实例创建的池大小。

于 2016-07-21T23:57:59.227 回答
2

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.

   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;
    };
于 2020-01-22T12:09:11.393 回答
1

单个node.js项目中的Mongoose和多个数据库

使用useDb来解决这个问题

例子

//product databse 
const myDB = mongoose.connection.useDb('product');
module.exports = myDB.model("Snack", snackSchema);
//user databse
const myDB = mongoose.connection.useDb('user');
module.exports = myDB.model("User", userSchema);
于 2020-09-07T03:01:48.953 回答