MongoDB native Node.js驱动程序与Mongoose相比性能糟糕,我做错了什么?

MongoDB native Node.js驱动程序与Mongoose相比性能糟糕,我做错了什么?,node.js,mongodb,mongoose,Node.js,Mongodb,Mongoose,我有一个简单的节点/express应用程序,需要获取存储在示例MongoDB集合(32位,本地主机,Windows)中的2个文档。我可以使用本地驱动程序或猫鼬ORM 使用本机驱动程序会使我的应用程序崩溃。做了一个ApacheBench(3300个请求,一次5个),整个事情都超时了 Completed 330 requests apr_pollset_poll: The timeout specified has expired (70007) 当通过Mongoose访问相同的MongoDB集合

我有一个简单的
节点/express
应用程序,需要获取存储在示例MongoDB集合
(32位,本地主机,Windows)
中的2个文档。我可以使用
本地驱动程序
猫鼬ORM

使用本机驱动程序会使我的应用程序崩溃。做了一个ApacheBench(3300个请求,一次5个),整个事情都超时了

Completed 330 requests
apr_pollset_poll: The timeout specified has expired (70007)
当通过Mongoose访问相同的MongoDB集合时,通过比较,它只会快速通过任务

...
Completed 2970 requests
Completed 3300 requests
Finished 3300 requests
...
Requests per second:    244.49 [#/sec] (mean)
Time per request:       61.353 [ms] (mean)
这是一个巨大的差异,显然我在使用本机驱动程序时犯了严重的错误。下面是这两种方法的代码以及数据库中存储的数据

数据库中只存储两个文档:

{
    "_id": "51bmdft4a487e771411ce8ef",
    "name": "Gintoki",
    "email": "sakata@yorozuya.com",
    "friends": [ "Shinpachi", "Kagura", "Tsukuyo" ]
},
{
    "_id": "51388p50bed4dghy4308745d",
    "name": "Elizabeth",
    "email": "eli@ossan.io",
    "friends": [ "Katsura" ]
}
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 );
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 );
使用本机MongoDB驱动程序:

{
    "_id": "51bmdft4a487e771411ce8ef",
    "name": "Gintoki",
    "email": "sakata@yorozuya.com",
    "friends": [ "Shinpachi", "Kagura", "Tsukuyo" ]
},
{
    "_id": "51388p50bed4dghy4308745d",
    "name": "Elizabeth",
    "email": "eli@ossan.io",
    "friends": [ "Katsura" ]
}
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 );
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 );
输出:超时一分钟后,仅完成
ab发出的3300个请求中的330个请求


使用猫鼬:

{
    "_id": "51bmdft4a487e771411ce8ef",
    "name": "Gintoki",
    "email": "sakata@yorozuya.com",
    "friends": [ "Shinpachi", "Kagura", "Tsukuyo" ]
},
{
    "_id": "51388p50bed4dghy4308745d",
    "name": "Elizabeth",
    "email": "eli@ossan.io",
    "friends": [ "Katsura" ]
}
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 );
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 );
输出:与本机驱动程序相比,速度非常快<代码>ab几秒钟内完成


有人能帮我找出本机驱动程序的错误吗?

可以肯定的是,在本机版本中,每个请求都会打开一个新的连接池。重新编写代码,以便在启动过程中,
MongoClient.connect
mongoose.connect
调用只进行一次

可以肯定的是,在本机版本中,每个请求都会打开一个新的连接池。重新编写代码,以便在启动期间,
MongoClient.connect
mongoose.connect
调用只进行一次

您是否尝试过从使用
到阵列
切换到使用
?right-.toArray()强制获取集合的完整内容,以将其转换为本地数组。您在mongoose中没有这样做,您不想在本机驱动程序中这样做。实际上,mongoose的
find
会将完整结果转换为一个数组,因此这是可比较的(此外,它只有两个文档)。可以肯定的是,在本机版本中,每个请求都会打开一个新的连接池。重新编写代码,以便在启动过程中,
MongoClient.connect
mongoose.connect
只调用一次。@johnyhk我自己也这么认为;每个请求创建一个新的DB conn是一个问题,但在Mongoose中,连接是在路由内部建立的,我假设本机驱动程序也是这样工作的。我现在将DB conn从路由中删除,很快将发布结果。@vjk2005您是否有可能发布(或链接到要点)您是如何重新编写本机驱动程序代码的?您是否尝试过从使用
toArray
切换到使用
stream
?right-.toArray()强制获取集合的完整内容,以将其转换为本地数组。您在mongoose中没有这样做,您不想在本机驱动程序中这样做。实际上,mongoose的
find
会将完整结果转换为一个数组,因此这是可比较的(此外,它只有两个文档)。可以肯定的是,在本机版本中,每个请求都会打开一个新的连接池。重新编写代码,以便在启动过程中,
MongoClient.connect
mongoose.connect
只调用一次。@johnyhk我自己也这么认为;每个请求创建一个新的DB conn是一个问题,但在Mongoose中,连接是在路由内部建立的,我假设本机驱动程序也是这样工作的。我现在将DB conn从路由中删除,很快将发布结果。@vjk2005您是否有机会发布(或链接到要点)您如何重新编写本机驱动程序代码?