提高 mongo 查询性能

aut*_*xer 3 mongodb node.js keystonejs

我正在使用名为 Keystone 的基于节点的 CMS 系统,该系统使用 MongoDB 作为数据存储,从而对数据和访问提供相当自由的控制。我有一个非常复杂的模型,称为Family,它有大约 250 个字段、一堆关系和十几个方法。我的网站上有一个表单,允许用户输入所需的信息来创建新的家庭记录,但是处理时间很长(在本地主机上为 12 秒,在我的 Heroku 实例上超过 30 秒)。我遇到的问题是 Heroku 对于运行超过 30 秒的任何进程都会发出应用程序错误,这意味着我需要优化我的查询。除一项功能外,所有处理都发生得非常快。下面是有问题的函数:

const Family = keystone.list( 'Family' );

exports.getNextRegistrationNumber = ( req, res, done ) => {

    console.time('get registration number');

    const locals = res.locals;

    Family.model.find()
        .select( 'registrationNumber' )
        .exec()
        .then( families => {

            // get an array of registration numbers
            const registrationNumbers = families.map( family => family.get( 'registrationNumber' ) );

            // get the largest registration number
            locals.newRegistrationNumber = Math.max( ...registrationNumbers ) + 1;

            console.timeEnd('get registration number');

            done();

        }, err => {

            console.timeEnd('get registration number');

            console.log( 'error setting registration number' );

            console.log( err );

            done();
        });
Run Code Online (Sandbox Code Playgroud)

};

我的处理.then()在几毫秒内发生,但是Family.model.find()执行时间太长。任何有关如何加快速度的建议将不胜感激。查询正在尝试挖掘大约 40,000 条家庭记录,并且该registrationNumber字段上已经有一个索引。

lax*_*089 6

then()执行速度很快但find()需要一段时间,这是有道理的;查找一组记录中的最大值是一个相对较快的数据库操作,而获取该组记录可能会非常耗时,具体取决于许多因素。

如果您只是读取数据并通过 REST 或某种可视化界面将其呈现给用户,则可以使用lean()它将返回纯 JavaScript 对象。默认情况下,您将返回一个mongoose.Document在您的情况下是不必要的,因为在读取查询后似乎没有任何数据操作;你只是在获取数据。

更重要的是,看来您只需要一条记录:最大的记录registrationNumberfindOne()当您在任何一组记录中查找一条记录时,您应该始终使用它,以最大限度地提高性能。

请参阅之前的答案findOne,详细介绍在 Node.js 实现中的使用,或参阅mongoDB 文档以获取有关此收集方法的一般信息。