简体   繁体   English

带有分页的 MongoDB 聚合查找在大量数据中运行缓慢

[英]MongoDB aggregation lookup with pagination is working slow in huge amount of data

I've a collection with more than 150 000 documents in MongoDB.我在 MongoDB 中有一个包含超过 150 000 个文档的集合。 I'm using Mongoose ODM v5.4.2 for MongoDB in Node.js.我在 Node.js 中为 MongoDB 使用 Mongoose ODM v5.4.2。 At the time of data retrieving I'm using Aggregation lookup with $skip and $limit for pagination.在检索数据时,我使用带有 $skip 和 $limit 的聚合查找进行分页。 My code is working fine but after 100k documents It's taking 10-15 seconds to retrieve data.我的代码工作正常,但在 10 万个文档之后检索数据需要 10-15 秒。 But I'm showing only 100 records at a time with the help of $skip and $limit.但是我在 $skip 和 $limit 的帮助下一次只显示 100 条记录。 I've already created index for foreignField.我已经为foreignField 创建了索引。 But still it's getting slow.但它仍然变得缓慢。

campaignTransactionsModel.aggregate([{
                    $match: {
                campaignId: new importModule.objectId(campaignData._id)
            }
                },
                {
                    $lookup: {
                        from: userDB,
                        localField: "userId",
                        foreignField: "_id",
                        as: "user"
                    },
                },
                {
                    $lookup: {
                        from: 'campaignterminalmodels',
                        localField: "terminalId",
                        foreignField: "_id",
                        as: "terminal"
                    },
                },
                {
                    '$facet': {
                        edges: [{
                                $sort: {
                                    [sortBy]: order
                                }
                            },
                            { $skip: skipValue },
                            { $limit: viewBy },
                        ]
                    }
                }
            ]).allowDiskUse(true).exec(function(err, docs) {
                console.log(docs);
            });

The query is taking longer because the server scans from beginning of input results(before skip stage) to skip the given number of docs and set the new result.查询需要更长的时间,因为服务器从输入结果的开头(在跳过阶段之前)开始扫描以跳过给定数量的文档并设置新结果。

From official MongoDB docs :来自官方 MongoDB 文档:

The cursor.skip() method requires the server to scan from the beginning of the input results set before beginning to return results. cursor.skip() 方法要求服务器在开始返回结果之前从输入结果集的开头开始扫描。 As the offset increases, cursor.skip() will become slower.随着偏移量的增加, cursor.skip() 会变慢。

You can use range queries to simulate similar result as of .skip() or skip stage(aggregation)您可以使用range查询来模拟与.skip()skip stage(aggregation)类似的结果

Using Range Queries使用范围查询

Range queries can use indexes to avoid scanning unwanted documents, typically yielding better performance as the offset grows compared to using cursor.skip() for pagination.范围查询可以使用索引来避免扫描不需要的文档,与使用 cursor.skip() 进行分页相比,随着偏移量的增加,通常会产生更好的性能。

Descending Order降序排列

Use this procedure to implement pagination with range queries:使用此过程通过范围查询实现分页:

  • Choose a field such as _id which generally changes in a consistent direction over time and has a unique index to prevent duplicate values选择一个字段,例如 _id,它通常会随着时间的推移在一致的方向上发生变化,并且具有唯一索引以防止出现重复值
  • Query for documents whose field is less than the start value using the $lt and cursor.sort() operators, and使用$ltcursor.sort()运算符查询字段小于起始值的文档,以及
  • Store the last-seen field value for the next query.为下一个查询存储上次看到的字段值。

Increasing Order - Query for documents whose field is less than the start value using the $gt and cursor.sort() operators, and递增顺序- 使用$gtcursor.sort()运算符查询字段小于起始值的文档,以及

Lets say the last doc you got has _id : objectid1, then you can query the docs who have _id : {$lt : objectid1} to get the docs in decreasing order.假设您获得的最后一个文档具有 _id : objectid1,那么您可以查询具有_id : {$lt : objectid1}的文档_id : {$lt : objectid1}以按降序获取文档。 and for incresing order you can query the docs who have _id : {$gt : objectid1}对于递增顺序,您可以查询具有_id : {$gt : objectid1}的文档_id : {$gt : objectid1}

Read official docs on Range queries for more information.阅读有关范围查询的官方文档以获取更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM