首页 > 解决方案 > 我不知道如何在同一个 mongodb 查询中使用 $group 、 $sum 和 $avg

问题描述

当我在一个小项目中工作时遇到问题时,我正在使用 mongodb 学习节点 js,我有一个订单集合,我想为它计算一些统计数据,比如总价格,它是所有订单价格的总和(orderPrice 的总和) ,总价格的平均值,即订单价格的总和除以订单数量,响应时间的总和和响应时间的平均值,这是数组:

[
 {  
    _id:"eyxwapfhiezfe664ec",
    orderPrice : 20,
    responseTime : 10, 
    createdAt :  2021-01-15T17:16:25.844Z
     
 }
 {
   _id:"eyxwlcfeojrfeoc",
    orderPrice : 50,
    responseTime : 10, 
    createdAt :  2021-01-15T17:16:25.844Z
     
 }
 {
   _id:"eyxwapfhiseflflpsssc",
    orderPrice : 20,
    responseTime : 7, 
    createdAt :  2021-01-15T17:16:25.844Z
     
 }
 {  
   _id:"eyxwapfhdfghkdfps",
    orderPrice : 12,
    responseTime : 5, 
    createdAt :  2021-01-16T17:16:25.844Z
     
 }
 {  
   _id:"eyxwapfhiezzefllc",
    orderPrice : 30,
    responseTime : 10, 
    createdAt :  2021-01-16T17:16:25.844Z
     
 }

]

对我来说更困难的事情是结果应该是一个一天的数组,所以我必须每天都做我提到的操作,这就是为什么我必须按天对数组中的文档进行分组,输出应该看起来像这

   [
   {
     day:2021-01-15 , 
     totalPrice: 90 , 
     avgPrice:30 , 
     totalTime: 27 , 
     avgTime: 9
   }
   {
     day:2021-01-16 , 
     totalPrice: 42 , 
     avgPrice:21 , 
     totalTime: 15 , 
     avgTime: 7.5
   }
   { 
     total: {
               totalPrice: 132 , 
               avgPrice:26,4 , 
               totalTime: 42 , 
               avgTime: 8.5
             }
   }
   ]

我不知道这是否可能仅使用 mongodb 聚合方法,如果不能,我如何使用最少的 javascript 代码来做到这一点,谢谢。

标签: node.jsmongodbmongooseaggregation-framework

解决方案


您必须使用 facet 来实现这一点,其中包含两个分组阶段。第一个将按 null 聚合以计算整个数据集的指标,第二个将按天分组。棘手的事情是从您的日期字符串中获取日期。

这是查询:

db.collection.aggregate([
  {
    "$facet": {
      "metricsTotal": [
        {
          $group: {
            _id: null,
            sumOrderPrice: {
              $sum: "$orderPrice"
            },
            avgOrderPrice: {
              $avg: "$orderPrice"
            },
            sumResponseTime: {
              $sum: "$responseTime"
            },
            avgResponseTime: {
              $avg: "$responseTime"
            }
          }
        }
      ],
      "metricsByDay": [
        {
          $group: {
            _id: {
              $dateFromParts: {
                "year": {
                  "$year": {
                    $dateFromString: {
                      "dateString": "$createdAt",
                      
                    }
                  }
                },
                "month": {
                  "$month": {
                    $dateFromString: {
                      "dateString": "$createdAt",
                      
                    }
                  }
                },
                "day": {
                  "$dayOfMonth": {
                    $dateFromString: {
                      "dateString": "$createdAt",
                      
                    }
                  },
                  
                }
              }
            },
            sumOrderPrice: {
              $sum: "$orderPrice"
            },
            avgOrderPrice: {
              $avg: "$orderPrice"
            },
            sumResponseTime: {
              $sum: "$responseTime"
            },
            avgResponseTime: {
              $avg: "$responseTime"
            }
          }
        }
      ]
    }
  }
])

你可以在这里测试


推荐阅读