I have a simple node/express app that needs to get the 2 documents stored inside a sample MongoDB collection (32-bit, localhost, Windows). I could use either the native driver or Mongoose ORM.
Going with the native driver tore my app apart. Did an ApacheBench (3300 requests, 5 at a time) and the whole thing timed out...
Completed 330 requests
apr_pollset_poll: The timeout specified has expired (70007)
The same MongoDB collection when accessed through Mongoose simply flies through the task by comparison...
...
Completed 2970 requests
Completed 3300 requests
Finished 3300 requests
...
Requests per second: 244.49 [#/sec] (mean)
Time per request: 61.353 [ms] (mean)
That is a massive difference and obviously I'm doing something terribly wrong when using the native driver. Here's the code for both the approaches along with the data stored in the DB.
Only two documents stored in the DB:
{
"_id": "51bmdft4a487e771411ce8ef",
"name": "Gintoki",
"email": "sakata@yorozuya.com",
"friends": [ "Shinpachi", "Kagura", "Tsukuyo" ]
},
{
"_id": "51388p50bed4dghy4308745d",
"name": "Elizabeth",
"email": "eli@ossan.io",
"friends": [ "Katsura" ]
}
Using the Native MongoDB driver:
var
app = require( 'express' )(),
MongoClient = require( 'mongodb' ).MongoClient,
DB_URL = 'mongodb://localhost:27017/testDB';
app.get( '/mongotest', function ( req, res ) {
MongoClient.connect( DB_URL, function ( err, db ) {
if( !err ) {
var collection = db.collection( 'People' );
collection.find().toArray(function(err, items) {
res.send( JSON.stringify( items ) );
})
}
})
})
app.listen( 5000 );
Output: Timed out afer a minute completing only 330 of the 3300 requests made by ab
Using Mongoose:
var
app = require( 'express' )(),
mongoose = require( 'mongoose' ),
DB_URL = 'mongodb://localhost:27017/testDB';
app.get( '/mongotest', function ( req, res ) {
mongoose.connect( DB_URL );
var
PeopleSchema = mongoose.Schema({ name: String, email: String, friends: Array }),
People = mongoose.model( 'People', PeopleSchema ),
db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function callback () {
People.find({}, function ( err, item ) {
res.send( item );
})
})
})
app.listen( 5000 );
Output: Blazing fast compared to the native driver. ab done in a few seconds.
Anyone help me figure out what I'm doing wrong with the native driver?
Pretty sure the problem is that in the native version a new connection pool is opened on each request. Rework your code so that the MongoClient.connect and the mongoose.connect calls are only made once, during startup