I'm writing some simple web app with Node.JS and want to use mongoDB as main data storage.
Node-mongodb-native driver requires to make chained calls before you actually can query or store data (open DB connection, authenticate, get collection).
Where is the best place to do this initialization - within each request handler or globally, when initializing application?
You are MUCH better putting the Mongo initialization outside of your request handler - otherwise it will re-connect for every page that is served:
var mongo = require('mongodb');
// our express (or any HTTP server)
var app = express.createServer();
// this variable will be used to hold the collection for use below
var mongoCollection = null;
// get the connection
var server = new mongo.Server('127.0.0.1', 27017, {auto_reconnect: true});
// get a handle on the database
var db = new Db('testdb', server);
db.open(function(error, databaseConnection){
databaseConnection.createCollection('testCollection', function(error, collection) {
if(!error){
mongoCollection = collection;
}
// now we have a connection - tell the express to start
app.listen(80);
});
});
app.use('/', function(req, res, next){
// here we can use the mongoCollection - it is already connected
// and will not-reconnect for each request (bad!)
})
Related
I see very few online posts when it comes to NodeJS with IBM DB2. I am new to NodeJS and having issues to configure connection pooling for my web app. I am successfully running node app with single connection in my local but not sure how to configure connection pooling. Below code is how I have it for single connection.
DBConnection JS:
module.exports = function(dbConnection)
{
var Pool = require('ibm_db').Pool;
var pool = new Pool();
pool.open("MY_CONNECTION_STRING",function(err,connection){
//error handling logic ...
dbConnection(connection);
});
}
App listener js:
var express = require('express');
var app = express();
app.listen(8080,function(){
console.log("server started..);
});
require('./DBConnection')(function(connection){
app.get('/getEmpId',function(req,res){
connection.query("MY_SQL_QUERY",function(error,results,fields){
//some other logic
res.send(results[0]);
//Closing connection
connection.close(function(err2) {
if(err2) console.log(err2);
});
});
});
}
Need your suggestions to setup connection pool where I can use one connection for each request when concurrent users are accessing and close the connection after serving request.
You can take a look at the brief samples provided with the IBM node-ibm_db driver. It has a section on Connection Pooling. The driver reuses the node-odbc pool and you need to invoke the open/close calls on the Pool object. Here is the sample taken from the node-ibm_db site:
var Pool = require("ibm_db").Pool
, pool = new Pool()
, cn = "DATABASE=dbname;HOSTNAME=hostname;PORT=port;PROTOCOL=TCPIP;UID=dbuser;PWD=xxx";
pool.open(cn, function (err, db) {
if (err) {
return console.log(err);
}
//db is now an open database connection and can be used like normal
//if we run some queries with db.query(...) and then call db.close();
//a connection to `cn` will be re-opened silently behind the scense
//and will be ready the next time we do `pool.open(cn)`
});
I have a locally hosted mongodb that I can connect to using mongodb.MongoClient.
Working code:
var mongoClient = require("mongodb").MongoClient;
...
var startApp = function(db) {
// Get our collections in an easy to use format
var database = {
chats: db.collection('chats'),
messages: db.collection('messages')
};
// Configure our routes
require('./app/routes')(app, database);
// START APP
// Start app on port
app.listen(port);
// Tell user the app is running
console.log("App running on port " + port);
// Expose app
exports = module.exports = app;
}
// DATABASE
var database = null;
mongoClient.connect(config.url, function(err, returnDB) {
if(err) {
console.log(err);
} else {
console.log("DB connected");
startApp(returnDB);
}
});
Legacy code that no longer works:
var mongoose = require('mongoose');
...
// Connect to DB
console.log('Connect to database (' + db.url + ')');
mongoose.connect(db.url);
I have added a callback to this connect method but it never gets called (error or no error, this connect function never gets to my callback).
This entire legacy app relies on the API using mongoose to talk to the database so I do not want to redo it all using mongodb. How can I fix this?
*config.url and db.url are loaded from the same file and it is a valid and running mongodb.
It was really easy to fix. Thanks #Bhavik for asking me what version I was using.
I updated mongoose to 4.8.1 by specifying the newest version in packages.json and the issue is resolved.
I am using the express framework and would like to connect to a mongodb without using mongoose, but with the native nodejs Mongodb driver. How can I do this without creating a new connection every time?
To handle get or post requests I currently open a new connection to the db for every request and close it on completion of the request. Is there a better way to do this? Thanks in advance.
Following the example from my comment, modifying it so that the app handles errors rather than failing to start the server.
var express = require('express');
var mongodb = require('mongodb');
var app = express();
var MongoClient = require('mongodb').MongoClient;
var dbURL = "mongodb://localhost:27017/integration_test";
var db;
// Initialize connection once
MongoClient.connect(dbURL, function(err, database) {
if(err) return console.error(err);
db = database;
// the Mongo driver recommends starting the server here
// because most apps *should* fail to start if they have no DB.
// If yours is the exception, move the server startup elsewhere.
});
// Reuse database object in request handlers
app.get("/", function(req, res, next) {
var collection = "replicaset_mongo_client_collection";
db.collection(collection).find({}, function(err, docs) {
if(err) return next(err);
docs.each(function(err, doc) {
if(doc) {
console.log(doc);
}
else {
res.end();
}
});
});
});
app.use(function(err, req, res){
// handle error here. For example, logging and
// returning a friendly error page
});
// Starting the app here will work, but some users
// will get errors if the db connection process is slow.
app.listen(3000);
console.log("Listening on port 3000");
var mongodb = require('mongodb');
var uri = 'mongodb://localhost:27017/dbname';
module.exports = function(callback) {
mongodb.MongoClient.connect(uri, callback);
};
Ad this snippet in a file say connect.js and then require this file(connect.js) in your file where you are declaring your functions for http requests.
I have an http server and every time it gets a post request, it is supposed to insert the data into MongoDB. This server is supposed to be constantly running and accepting thousands of request in any given second.
How can I maximize the efficiency and speed of my code? I feel like my current code is not fast enough and furthermore wastes CPU power when it makes a new db every time it receives a request.
My current layout
var server = http.createServer(function (req, res) {
req.on('data', function(chunk) {
//Receive my data
});
req.on('end', function() {
//JSON parse my data
var db = new Db('test', new Server("111.111.11.111", 27017,{auto_reconnect: false}), {safe: true});
db.open(function(err, db) {
//Insert data into DB
db.close();
});
});
}); //End Http server
server.listen(8999);
I have tried replacing db.open with MongoClient.connect, but that considerably slows down processing and I don't know why. In this case, the older version of MongoDB Native for node js seems to work faster.
You'll want to shift to an approach where you open a large pool of connections during startup that are shared by your HTTP request handlers. To tweak the MongoDB connection pool size to suit whatever scalability needs you have, pass an options parameter to your MongoClient.connect call.
var options = {
server: {
// The number of pooled connection available to your app.
poolSize: 100
}
};
mongodb.MongoClient.connect('mongodb://111.111.11.111/test', options,
function(err, db) {
var server = http.createServer(function (req, res) {
// Your req.on calls go here, directly using db rather than creating
// new instances. Don't close db either.
});
server.listen(8999);
}
);
Not sure if this would be better, but you can encapsulate that server inside the db, therefore persisting the connection:
var db = new Db('test', new Server("111.111.11.111", 27017,{auto_reconnect: false}), {safe: true});
db.open(function(err, db) {
var server = http.createServer(function (req, res) {
//now do stuff thru constant open connection
});
db.close();
});
I have two same app running on different one for demo and one for developement .and m using the redis database to store key value, how can i seperate redis database for these two different app. m using node.js for redis client. and m using this https://github.com/mranney/node_redis/ redis client.
how to seperate redis database for same app in node.
You can use the .select(db, callback) function in node_redis.
var redis = require('redis'),
db = redis.createClient();
db.select(1, function(err,res){
// you'll want to check that the select was successful here
// if(err) return err;
db.set('key', 'string'); // this will be posted to database 1 rather than db 0
});
If you are using expressjs, you can set a development and production environment variable to automatically set which database you are using.
var express = require('express'),
app = express.createServer();
app.configure('development', function(){
// development options go here
app.set('redisdb', 5);
});
app.configure('production', function(){
// production options here
app.set('redisdb', 0);
});
Then you can make one call to db.select() and have the options set for production or development.
db.select(app.get('redisdb'), function(err,res){ // app.get will return the value you set above
// do something here
});
More information on dev/production in expressjs: http://expressjs.com/guide.html#configuration
The node_redis .select(db, callback) callback function will return OK in the second argument if the database is selected. An example of this can be seen on the Usage section of the node_redis readme.