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

时间:2013-10-20 06:51:53

标签: javascript node.js mongodb mongoose database

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

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

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

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

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

6 个答案:

答案 0 :(得分:178)

根据the fine manualcreateConnection() 可以用于连接多个数据库。

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

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

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

答案 1 :(得分:32)

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

在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访问多个数据库。

答案 2 :(得分:24)

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

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

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

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

在处理单独的数据源时,以及当您希望为每个用户或请求创建单独的数据库上下文时,这非常有用。您需要小心,因为在执行此操作时可能会创建大量连接。确保在不需要实例时调用disconnect(),并限制每个实例创建的池大小。

答案 3 :(得分:19)

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

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

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是您的数据库名称。

答案 4 :(得分:2)

一个经过优化的解决方案(对我来说至少是这样)。将其写入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;
    };

答案 5 :(得分:0)

在单个node.js项目中使用猫鼬和多个数据库

使用 useDb 解决此问题

示例

//产品数据库

const myDB = mongoose.connection.useDb('product');

module.exports = myDB.model(“ Snack”,快餐模式);

//用户数据库

const myDB = mongoose.connection.useDb('user');

module.exports = myDB.model(“ User”,userSchema);