具有分页功能的MongoDB聚合查找在处理大量数据时工作缓慢

时间:2019-07-03 04:23:54

标签: node.js mongodb mongoose

我在MongoDB中拥有一个包含15万多个文档的集合。我在Node.js中为MongoDB使用Mongoose ODM v5.4.2。在数据检索时,我正在使用带有$ skip和$ limit的聚合查找进行分页。我的代码运行正常,但是在100k文档之后,需要10-15秒才能检索到数据。但是在$ skip和$ limit的帮助下,我一次只显示100条记录。我已经为foreignField创建了索引。但它仍在变慢。

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);
            });

1 个答案:

答案 0 :(得分:1)

查询花费的时间更长,因为服务器从输入结果的开头(在跳过阶段之前)开始扫描以跳过给定数量的文档并设置新结果。

来自MongoDB官方文档:

  

cursor.skip()方法要求服务器从   开始返回结果之前输入结果集的开始。   随着偏移量的增加,cursor.skip()会变慢。

您可以使用range个查询来模拟与.skip()skip stage(aggregation)相似的结果

  

使用范围查询

     

范围查询可以使用索引来避免扫描不需要的文档,   与偏移相比,随着偏移的增加,通常会产生更好的性能   使用cursor.skip()进行分页。

     

降序

     

使用此过程来实现范围查询的分页:

     
      
  • 选择诸如_id之类的字段,该字段通常会以一致的方式更改   随时间变化的方向,并具有唯一索引以防止重复   值
  •   
  • 查询字段小于起始值的文档   使用$ltcursor.sort()运算符,以及
  •   
  • 存储下一个查询的上次看到的字段值。
  •   
     

订单递增    -查询其字段小于起始值的文档   使用$gtcursor.sort()运算符,以及

假设您获得的最后一个文档具有_id:objectid1,那么您可以查询具有_id : {$lt : objectid1}的文档,以降序获取文档。对于递增顺序,您可以查询具有_id : {$gt : objectid1}

的文档

阅读Range queries上的官方文档以了解更多信息。