在express.js中连接到Mongodb-Native-Driver

我在express.js应用程序中使用mongodb本地驱动程序。 我在数据库中有大约6个集合,所以我创build了6个js文件,每个文件都有一个作为javascript对象的集合(例如, function collection(){} ),原型函数处理这些集合的所有操作。 我认为这将是一个很好的build筑。

但是我遇到的问题是如何连接到数据库? 我应该在每个文件中创build一个连接并使用它们吗? 我认为这将是一个矫枉过正的问题,因为mongodb-native-driver中的连接创build了一个连接池,其中有几个连接是不合理的。

那么如何创build一个连接池并将其用于所有collections.js文件? 我想要像在mongoose中实现的连接。 让我知道,如果我的应用程序的体系结构的任何思维过程是错误的。

使用Mongoose可以解决这些问题,但是我已经在几个地方读过,它比native-driver慢,我也更喜欢一个无模式的模型。

编辑:我用模型创build了一个模块。 每个集合都在一个文件中,并将数据库作为参数。 现在在index.js文件中,我调用了数据库连接,并在从连接中获取数据库后保留了一个variablesdb。 ( 我使用了自动重新连接function来确保连接没有丢失 )。 在同一个index.js文件中,我像这样导出了每个集合

 exports.model1 = require('./model1').(db) exprorts.model2 = require('./model2').(db) 

这确保了数据库部分只在一个模块中处理,并且应用程序只会调用每个model.js文件导出的函数,如save()fincdbyid()等等( whatever you do in the function is upto you to implement fincdbyid() whatever you do in the function is upto you to implement )。

如何连接到数据库?

为了使用MongoDB本地驱动程序进行连接,您需要执行以下操作:

 var util = require('util'); var mongodb = require('mongodb'); var client = mongodb.MongoClient; var auth = { user: 'username', pass: 'password', host: 'hostname', port: 1337, name: 'databaseName' }; var uri = util.format('mongodb://%s:%s@%s:%d/%s', auth.user, auth.pass, auth.host, auth.port, auth.name); /** Connect to the Mongo database at the URI using the client */ client.connect(uri, { auto_reconnect: true }, function (err, database) { if (err) throw err; else if (!database) console.log('Unknown error connecting to database'); else { console.log('Connected to MongoDB database server at:'); console.log('\n\t%s\n', uri); // Create or access collections, etc here using the database object } }); 

一个基本的连接是这样设置的。 这就是我可以给你的只是你想要的基本描述。 发布一些你已经得到的代码,以获得更具体的帮助。

我应该在每个文件中创build一个连接并使用它们吗?

没有。

那么如何创build一个连接池并将其用于所有collections.js文件?

你可以用上面的代码创build一个单独的文件,让我们把它dbmanager.js连接到数据库的dbmanager.js 。 导出像createUserdeleteUser等这样的函数,在你的数据库上运行,然后导出如下的函数:

 module.exports = { createUser: function () { ; }, deleteUser: function () { ; } }; 

然后你可以从另一个文件中得到这样的require

 var dbman = require('./dbmanager'); dbman.createUser(userData); // using connection established in `dbmanager.js` 

编辑:因为我们正在处理JavaScript和单个线程,本地驱动程序确实自动为您处理连接池。 你可以在下面的StackOverflow链接中查找这个更多的确认。 OP也在这个问题中说明了这一点。 这意味着client.connect 只能由服务器的一个实例调用一次database对象从调用client.connect成功检索后,该database对象应该在应用程序的整个实例中重用。 这很容易通过使用Node.JS提供的模块模式来完成。

我的build议是创build一个模块或一组模块作为与数据库交互的单一联系点。 在我的应用程序中,我通常有一个依赖本机驱动程序的模块,调用require('mongodb') 。 我的应用程序中的所有其他模块不会直接访问数据库,而是所有操作必须由此数据库模块进行协调。

这将处理本地驱动程序的所有代码封装到单个模块或一组模块中。 OP似乎认为我所发布的简单代码示例存在一个问题,在我的示例中描述了一个“单个大闭包”的问题。 这是非常基本的东西,所以我在这里添加了关于基本架构的说明,但是我仍然不觉得需要更改任何代码。

OP也似乎认为可能在这里build立多个连接。 这是不可能的这个设置。 如果你创build了一个像我上面build议的模块,那么第一次require('./dbmanager')被调用时,它将执行文件dbmanager.js的代码返回module.exports对象。 exports对象被caching,并且在每次后续调用require('./dbmanager') ,但是, dbmanager.js的代码只会执行第一个require

如果你不想创build一个这样的模块,那么另外一个select就是只导出传递给client.connectcallback的database ,并在整个应用程序的不同位置直接使用它。 不过,我反对这个build议,不pipeOP的问题。

类似的,可能复制Stackoverflow的问题,其中包括:

  • 如何在nodejs webapp中pipe理mongodb连接
  • Node.JS和MongoDB,重用DB对象
  • Node.JS – 处理MongoDB连接的正确方法是什么?

正如接受的答案所说 – 你应该只为所有传入的请求创build一个连接,并重用它,但答案是缺less解决scheme,这将创build和caching连接。 我写了快递中间件来实现这个 – express-mongo-db 。 乍一看这个任务是微不足道的,大多数人使用这种types的代码:

 var db; function createConnection(req, res, next) { if (db) { req.db = db; next(); } client.connect(uri, { auto_reconnect: true }, function (err, database) { req.db = db = databse; next(); }); } app.use(createConnection); 

但是,当多个请求同时到达时,此代码将导致连接泄漏,并且db未定义。 express-mongo-db在需要模块(不是第一次请求到达时)时,通过保持传入客户端和仅connect一次connect来解决此问题。

希望你觉得它有用。

我只是认为我会添加自己的MongoDB连接方法为其他感兴趣的人或有不同的方法的问题

这个方法假定你不需要authentication(我在本地主机上使用这个)

authentication仍然很容易实现

 var MongoClient = require('mongodb').MongoClient; var Server = require('mongodb').Server; var client = new MongoClient(new Server('localhost',27017,{ socketOptions: {connectTimeoutMS: 500}, poolSize:5, auto_reconnect:true }, { numberOfRetries:3, retryMilliseconds: 500 })); client.open(function(err, client) { if(err) { console.log("Connection Failed Via Client Object."); } else { var db = client.db("theDbName"); if(db) { console.log("Connected Via Client Object . . ."); db.logout(function(err,result) { if(!err) { console.log("Logged out successfully"); } client.close(); console.log("Connection closed"); }); } } }); 

值得一提的是布拉德·达维(Brad Davley)在他的着作 (231-232页)中介绍了这种方法,