如何通过NodeJs应用程序和模块正确地重用连接到Mongodb

我一直在阅读和阅读,仍然困惑于什么是跨整个NodeJs应用程序共享同一个数据库(MongoDb)连接的最佳方式。 据我所知,连接应该是开放时,应用程序启动和重用模块之间。 我目前的想法是最好的方法是server.js (所有东西都开始的主文件)连接到数据库,并创build传递给模块的对象variables。 一旦连接,这个variables将被模块代码使用,并且这个连接保持打开状态。 例如:

  var MongoClient = require('mongodb').MongoClient; var mongo = {}; // this is passed to modules and code MongoClient.connect("mongodb://localhost:27017/marankings", function(err, db) { if (!err) { console.log("We are connected"); // these tables will be passed to modules as part of mongo object mongo.dbUsers = db.collection("users"); mongo.dbDisciplines = db.collection("disciplines"); console.log("aaa " + users.getAll()); // displays object and this can be used from inside modules } else console.log(err); }); var users = new(require("./models/user"))(app, mongo); console.log("bbb " + users.getAll()); // not connected at the very first time so displays undefined 

那么另一个模块models/user看起来像这样:

 Users = function(app, mongo) { Users.prototype.addUser = function() { console.log("add user"); } Users.prototype.getAll = function() { return "all users " + mongo.dbUsers; } } module.exports = Users; 

现在我有可怕的感觉,这是错误的,所以这种方法有什么明显的问题,如果是的话,如何使它更好?

您可以创build一个mongoUtil.js模块,该模块具有连接到mongo并返回mongo数据库实例的function:

 var MongoClient = require( 'mongodb' ).MongoClient; var _db; module.exports = { connectToServer: function( callback ) { MongoClient.connect( "mongodb://localhost:27017/marankings", function( err, db ) { _db = db; return callback( err ); } ); }, getDb: function() { return _db; } }; 

要使用它,你可以在你的app.js做到这一点:

 var mongoUtil = require( 'mongoUtil' ); mongoUtil.connectToServer( function( err ) { // start the rest of your app here } ); 

然后,当你需要在某个地方访问mongo时,你可以这样做:

 var mongoUtil = require( 'mongoUtil' ); var db = mongoUtil.getDb(); db.collection( 'users' ).find(); 

这个工作的原因是,在节点中,当模块require 'd'时,它们只会被加载/来源一次,所以你将只能得到_db一个实例,而mongoUtil.getDb()将总是返回同一个实例。

请注意,代码未经testing。

go-oleg基本上是正确的,但在这些日子里,你(可能)不想使用“mongodb”本身,而是使用一些框架,这会为你做很多“脏活”。

例如,mongoose是最常见的之一。 这是我们在最初的server.js文件中所具有的:

 const mongoose = require('mongoose'); const options = {server: {socketOptions: {keepAlive: 1}}}; mongoose.connect(config.db, options); 

这是设置它所需的一切。 现在在代码中的任何地方使用

 const mongoose = require('mongoose'); 

你得到你用mongoose.connect设置的实例

基于go-oleg的例子,我用现代语法来做这件事。 我的testing和function。

我在代码中添加了一些注释。

./db/mongodb.js

  const MongoClient = require('mongodb').MongoClient const uri = 'mongodb://user:password@localhost:27017/dbName' let _db const connectDB = async (callback) => { try { MongoClient.connect(uri, (err, db) => { _db = db return callback(err) }) } catch (e) { throw e } } const getDB = () => _db const disconnectDB = () => _db.close() module.exports = { connectDB, getDB, disconnectDB } 

./index.js

  // Load MongoDB utils const MongoDB = require('./db/mongodb') // Load queries & mutations const Users = require('./users') // Improve debugging process.on('unhandledRejection', (reason, p) => { console.log('Unhandled Rejection at:', p, 'reason:', reason) }) const seedUser = { name: 'Bob Alice', email: 'test@dev.null', bonusSetting: true } // Connect to MongoDB and put server instantiation code inside // because we start the connection first MongoDB.connectDB(async (err) => { if (err) throw err // Load db & collections const db = MongoDB.getDB() const users = db.collection('users') try { // Run some sample operations // and pass users collection into models const newUser = await Users.createUser(users, seedUser) const listUsers = await Users.getUsers(users) const findUser = await Users.findUserById(users, newUser._id) console.log('CREATE USER') console.log(newUser) console.log('GET ALL USERS') console.log(listUsers) console.log('FIND USER') console.log(findUser) } catch (e) { throw e } const desired = true if (desired) { // Use disconnectDB for clean driver disconnect MongoDB.disconnectDB() process.exit(0) } // Server code anywhere above here inside connectDB() }) 

./users/index.js

  const ObjectID = require('mongodb').ObjectID // Notice how the users collection is passed into the models const createUser = async (users, user) => { try { const results = await users.insertOne(user) return results.ops[0] } catch (e) { throw e } } const getUsers = async (users) => { try { const results = await users.find().toArray() return results } catch (e) { throw e } } const findUserById = async (users, id) => { try { if (!ObjectID.isValid(id)) throw 'Invalid MongoDB ID.' const results = await users.findOne(ObjectID(id)) return results } catch (e) { throw e } } // Export garbage as methods on the Users object module.exports = { createUser, getUsers, findUserById } 

如果您使用Express,那么您可以使用express-mongo-db模块,它允许您在请求对象中获取数据库连接。

安装

 npm install --save express-mongo-db 

server.js

 var app = require('express')(); var expressMongoDb = require('express-mongo-db'); app.use(expressMongoDb('mongodb://localhost/test')); 

路线/ users.js

 app.get('/', function (req, res, next) { req.db // => Db object });