How to use the connection with Mongodb through the application and NodeJs modules

I read and read and am still confused by what is the best way to share the same database connection (MongoDb) throughout the entire NodeJs application. As far as I understand, the connection should be open when the application starts and is reused between modules. My current idea of ​​a better way is that server.js (the main file where it all starts) connects to the database and creates an object variable that is passed to the modules. Once connected, this variable will be used by the module code as needed, and this connection remains open. For example:.

  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 

then another models/user module looks like this:

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

Now I have a terrible feeling that this is wrong, so are there obvious problems with this approach, and if so, how to do it better?

+84
javascript mongodb express
Jul 08 '14 at 0:22
source share
12 answers

You can create the mongoUtil.js module, which has functions for connecting to mongo and for returning an instance of mongo db:

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

To use it, you will do it in your app.js :

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

And then when you need access to mongo somewhere, you can do this:

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

The reason this works is because in node, when the modules require 'd, they only load / get once, so you will always have only one instance of _db and mongoUtil.getDb() always return the same instance .

Note, the code is not verified.

+122
Jul 08 '14 at 14:29
source share

If you use Express, then you can use the express-mongo-db module , which allows you to get the db connection in the request object.

set

 npm install --save express-mongo-db 

server.js

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

routes / users.js

 app.get('/', function (req, res, next) { req.db // => Db object }); 
+16
Jun 18 '17 at 6:25
source share

Here's how I do it with modern syntax based on go-oleg example. Mine is tested and functional.

I have added some comments to the code.

./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 } 
+16
Aug 26 '17 at 23:20
source share

go-oleg is right in principle, but these days you (probably) do not want to use "mongodb" yourself, rather use some framework that will do a lot of "dirty work" for you.

For example, mongoose is one of the most common. This is what we have in our server.js source file:

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

This is all you need to configure it. Now use this in your code

 const mongoose = require('mongoose'); 

And you will get the instance that you created using mongoose.connect

+8
Jul 13 '16 at 8:46
source share

Initialize the connection as a promise:

 const MongoClient = require('mongodb').MongoClient const uri = 'mongodb://...' const client = new MongoClient(uri) const connection = client.connect() // initialized connection 

And then call the connection whenever you want to perform an action on the database:

  // if I want to insert into the database... const connect = connection connect.then(() => { const doc = { id: 3 } const db = client.db('database_name') const coll = db.collection('collection_name') coll.insertOne(doc, (err, result) => { if(err) throw err }) }) 
+6
Oct 13 '18 at 7:54
source share

Verified solution based on the accepted answer:

mongodbutil.js:

 var MongoClient = require( 'mongodb' ).MongoClient; var _db; module.exports = { connectToServer: function( callback ) { MongoClient.connect( "<connection string>", function( err, client ) { _db = client.db("<collection name>"); return callback( err ); } ); }, getDb: function() { return _db; } }; 

app.js:

 var createError = require('http-errors'); var express = require('express'); var path = require('path'); var cookieParser = require('cookie-parser'); var logger = require('morgan'); var app = express(); app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); app.use(logger('dev')); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); var mongodbutil = require( './mongodbutil' ); mongodbutil.connectToServer( function( err ) { //app goes online once this callback occurs var indexRouter = require('./routes/index'); var usersRouter = require('./routes/users'); var companiesRouter = require('./routes/companies'); var activitiesRouter = require('./routes/activities'); var registerRouter = require('./routes/register'); app.use('/', indexRouter); app.use('/users', usersRouter); app.use('/companies', companiesRouter); app.use('/activities', activitiesRouter); app.use('/register', registerRouter); // catch 404 and forward to error handler app.use(function(req, res, next) { next(createError(404)); }); // error handler app.use(function(err, req, res, next) { res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; res.status(err.status || 500); res.render('error'); }); //end of calback }); module.exports = app; 

activity .js - route:

 var express = require('express'); var router = express.Router(); var mongodbutil = require( '../mongodbutil' ); var db = mongodbutil.getDb(); router.get('/', (req, res, next) => { db.collection('activities').find().toArray((err, results) => { if (err) return console.log(err) res.render('activities', {activities: results, title: "Activities"}) }); }); router.post('/', (req, res) => { db.collection('activities').save(req.body, (err, result) => { if (err) return console.log(err) res.redirect('/activities') }) }); module.exports = router; 
+4
May 30 '18 at 10:49
source share

There are many ways you can adapt configuration objects locally, but in general this is similar to how your code is laid out, albeit with more modern JS syntax. It can be easily rewritten into prototypes and callbacks if this is your requirement.

mongo.js

 const { MongoClient } = require('mongodb'); const config = require('./config'); const Users = require('./Users'); const conf = config.get('mongodb'); class MongoBot { constructor() { const url = 'mongodb://${conf.hosts.join(',')}'; this.client = new MongoClient(url, conf.opts); } async init() { await this.client.connect(); console.log('connected'); this.db = this.client.db(conf.db); this.Users = new Users(this.db); } } module.exports = new MongoBot(); 

Users.js

 class User { constructor(db) { this.collection = db.collection('users'); } async addUser(user) { const newUser = await this.collection.insertOne(user); return newUser; } } module.exports = User; 

app.js

 const mongo = require('./mongo'); async function start() { // other app startup stuff... await mongo.init(); // other app startup stuff... } start(); 

someFile.js

 const { Users } = require('./mongo'); async function someFunction(userInfo) { const user = await Users.addUser(userInfo); return user; } 
+3
Mar 29 '19 at 19:09
source share

we can create a dbconnection file such as dbconnection.js

 const MongoClient = require('mongodb').MongoClient const mongo_url = process.env.MONGO_URL; module.exports = { connect: async function(callback) { var connection; await new Promise((resolve, reject) => { MongoClient.connect(mongo_url, { useNewUrlParser: true }, (err, database) => { if (err) reject(); else { connection = database; resolve(); } }); }); return connection; } }; 

and then use this file in your application as

 var connection = require('../dbconnection'); 

and then use like this inside your asynchronous function

 db = await connection.connect(); 

I hope it works

+2
Feb 01 '19 at 11:51
source share

If you decide to use mongoose in your application, edit the app.js file with the following snippet.

app.js

 const mongoose = require('mongoose'); mongoose.connect('mongodb://localhost:27017/Your_Data_Base_Name', {useNewUrlParser:true}) .then((res) => { console.log(' ########### Connected to mongDB ###########'); }) .catch((err) => { console.log('Error in connecting to mongoDb' + err); });' 

Next step: Define the models for your application that need them, and, for example, do the CRUD operation directly

blogSchema.js

  const mongoose = require('mongoose'); const Schema = mongoose.Schema; const blogSchema = new Schema({ _id : mongoose.Schema.Types.ObjectId, title : { type : 'String', unique : true, required : true }, description : String, comments : [{type : mongoose.Schema.Types.ObjectId, ref: 'Comment'}] }); module.exports = mongoose.model('Blog', blogSchema); 

Using createBlog.js

 const Blog = require('../models/blogSchema'); exports.createBlog = (req, res, next) => { const blog = new Blog({ _id : new mongoose.Types.ObjectId, title : req.body.title, description : req.body.description, }); blog.save((err, blog) => { if(err){ console.log('Server Error save fun failed'); res.status(500).json({ msg : "Error occured on server side", err : err }) }else{ //do something.... } 

You do not need to always connect to mogoDB ....

+2
Apr 02 '19 at 4:57
source share
 var MongoClient = require('mongodb').MongoClient; var url = 'mongodb://localhost:27017/'; var Pro1; module.exports = { DBConnection:async function() { Pro1 = new Promise(async function(resolve,reject){ MongoClient.connect(url, { useNewUrlParser: true },function(err, db) { if (err) throw err; resolve(db); }); }); }, getDB:async function(Blockchain , Context) { bc = Blockchain; contx = Context; Pro1.then(function(_db) { var dbo = _db.db('dbname'); dbo.collection('collectionname').find().limit(1).skip(0).toArray(function(err,result) { if (err) throw err; console.log(result); }); }); }, closeDB:async function() { Pro1.then(function(_db){ _db.close(); }); } }; 
+2
Apr 02 '19 at 8:35
source share

I just point to the existing answer to this question

stack overflow

full credit goes to the original answer that Alexander gives. yes, you can improve this answer using es6 classes.

0
Apr 05 '19 at 7:17
source share

I'm a little late for this, but I will add my solution too. This is a much more interesting approach compared to the answers here.

In any case, if you are using MongoDB version 4.0 and Node.js 3.0 (or more isConnected() versions), you can use isConnected() from MongoClient .

 const MongoClient = require('mongodb').MongoClient; const uri = "<your connection url>"; const client = new MongoClient(uri, { useNewUrlParser: true }); if (client.isConnected()) { execute(); } else { client.connect().then(function () { execute(); }); } function execute() { // Do anything here // Ex: client.db("mydb").collection("mycol"); } 

This worked fine for me. Hope it helps.

0
Apr 19 '19 at 13:02
source share



All Articles