运行查询时,mongo上的聚合函数运行速度非常慢

Posted

技术标签:

【中文标题】运行查询时,mongo上的聚合函数运行速度非常慢【英文标题】:Aggregate function on mongo running very slow when running query 【发布时间】:2019-12-16 08:07:01 【问题描述】:

尝试在 Mongo 上运行聚合函数的查询,当我希望的结果不到一秒时,该查询当前需要 16 秒


  "$lookup": 
    "from": "session_attendances",
    "let":  "id": "$_id" ,
    "pipeline": [
      
        "$match": 
          "$expr": 
            "$eq": ["$student", "$$id"]
          
        
      ,
      
        "$project": 
          "attendance_code": "$attendance_code"
        
      
    ],
    "as": "attendance"
  
,

  // keep only matched students, can skip this and modifiy the next phase incase no such documents exists.
  "$unwind": "$attendance"
,

  "$lookup": 
    "from": "attendance_codes",
    "let":  "attendance_code": "$attendance.attendance_code" ,
    "pipeline": [
      
        "$project": 
          "type": 1
        
      ,
      
        "$match": 
          "$expr": 
            "$eq": ["$_id", "$$attendance_code"]
          
        
      
    ],
    "as": "attendance_code"
  
,

  //again assuming we want to keep matched docs otherwise why lookup?
  "$unwind": "$attendance_code"
,

  "$group": 
    "_id":  "a": "$attendance.attendance_code", "id": "$_id" ,
    "total":  "$sum": 1 ,
    "data":  "$first": "$$ROOT"  // if u want to keep document data
  

希望有人可以回答我的代码的哪一部分导致运行时间如此缓慢。

【问题讨论】:

您可能会在以下帖子中找到答案:***.com/questions/43742635/… 【参考方案1】:

不清楚你的最终目标是什么,如果你想澄清它会帮助我为你当前的聚合提供一个替代方案

话虽如此,第二个查找阶段是“无用的”,因为您在不使用它获得的任何数据的情况下立即进行分组,删除它仍然可以获得完全相同的结果并节省一些时间。

假设由于某种原因需要第二次查找,我建议不要嵌套它,而是在第一次查找之后使用,如下所示:


        $lookup: 
            from: 'session_attendances',
            let:  'id': '$_id' ,
            pipeline: [
                
                    "$match": 
                        "$expr": 
                            "$eq": ["$student", "$$id"]
                        
                    
                
                ,
                    $project: 
                        attendance_code: '$attendance_code'
                    
                
            ],
            as: 'attendance'
        
    ,
    // keep only matched students, can skip this and modifiy the next phase incase no such documents exists.
       $unwind: "$attendance" 
    ,
    
       $lookup: 
           from: 'attendance_codes',
           let:  'attendance_code': '$attendance.attendance_code' ,
            pipeline: [
               
                 $project: 
                    type: 1
                 
               ,
               
                 "$match": 
                     "$expr": 
                         "$eq": ["$_id", "$$attendance_code"]
                   
               ],
               as: 'attendance_code'
                    
         
   ,
    //again assuming we want to keep matched docs otherwise why lookup?
     $unwind: "$attendance_code"
   ,
   
        $group: 
            _id: a: "$attendance.attendance_code", id: "$_id"
            total:  $sum: 1 ,
            data: $first: "$$ROOT" // if u want to keep document data
        
   

这应该会给你更好的性能,我也建议放弃项目阶段,除非文档非常大,否则这通常不会帮助性能反而会损害它。

【讨论】:

这是对所需内容以及为什么***.com/questions/57418389/… 的更详细说明注意使用不同的方法

以上是关于运行查询时,mongo上的聚合函数运行速度非常慢的主要内容,如果未能解决你的问题,请参考以下文章

Mongo 聚合游标和计数

pymongo中带有forEach函数的Mongo聚合查询不起作用

Spring Mongo 聚合查询以从 MongoDB 获取不同的国家名称和国家代码

将 SQL 查询转换为 Mongo 聚合

mongoDB应用篇-mongo聚合查询

mongo聚合函数count问题