提高 mongo 查询性能

improve mongo query performance

我正在使用一个名为 Keystone 的基于节点的 CMS 系统,它使用 MongoDB 作为数据存储,对数据和访问提供相当自由的控制。我有一个名为 Family 的非常复杂的模型,它有大约 250 个字段、一堆关系和十几个方法。我的网站上有一个表格,允许用户输入所需信息以创建新的 Family 记录,但是处理时间是 运行ning 长(在本地主机上为 12s在我的 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();
        });

};

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

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

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

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

有关此收集方法的一般信息,请参阅 previous answer detailing using findOne in a node.js implementation, or see mongoDB documentation