MongoDB聚合查询返回集合中每年每月的条目总数,按位置值分组

Posted

技术标签:

【中文标题】MongoDB聚合查询返回集合中每年每月的条目总数,按位置值分组【英文标题】:MongoDB aggregation query to return total number of entries in a collection per year-month, grouped by a location value 【发布时间】:2020-06-19 15:14:55 【问题描述】:

我正在尝试编写一个 mongo 聚合查询,它返回每个 年月 集合中的条目总数,按 位置 分组。

这是所需输出的示例:

  [
          
            _id: 'Location 1',
            reviews: [
               total: 12, date: '03-2019' ,
               total: 55, date: '04-2019' ,
               total: 9, date: '05-2019' 
            ]
          ,
          
            _id: 'Location 2',
            reviews: [
               total: 8, date: '03-2019' ,
               total: 35, date: '04-2019' ,
               total: 12, date: '05-2019' 
            ]
          
        ];

这是架构的截断示例:

  
    branchId:  type: String, required: true ,
    orgId:  type: String, required: true ,
    stars:  type: Number, default: 0 ,
    reviewUpdatedAt:  type: Date, default: Date.now 
  

我能够以各种方式返回数据,但在获取所需输出时遇到问题。以下是我遇到障碍的一些示例查询。基本上我在尝试对每月的总条目进行分组时遇到问题,然后按 branchId / location 进一步分组。

以下是按年月分组的示例。响应包含每个 branchId 的计数,但 _ids 对于每个分支的月份-年份都有重复项。我需要 _id 作为位置,并有一个包含总计和年月的数组,如上面所需输出的示例所示。

[
      
        $match: 
            stars: $exists: true, $gte: 1,
            orgId: '100003'
       //   reviewUpdatedAt:  $gte: new Date(fromDate), $lte: new Date(toDate) 
        
      ,

      
        $group: 
          _id:  $dateToString:  format: '%Y-%m', date: '$reviewUpdatedAt' ,
          branchId: $addToSet: '$branchId',
          total:  $sum: 1 
        
      ,
        
          $unwind: '$branchId'
        ,
       $sort:  _id: 1  
    ]

在上面的示例中,我已经成功调整了组和 $unwind 语句,如下所示:


    $group: 
        _id: '$branchId',
        date:  $addToSet:  $dateToString:  format: '%Y-%m', date: '$reviewUpdatedAt'   ,
        total:  $sum: 1 
    
,
 $unwind: '$date' 

但是,总的 $sum 并不准确,并且对于每个 branchId 条目都会重复。如何修改上述查询以产生所需的输出?任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

您可以尝试以下查询:

db.collection.aggregate([
  
    $group: 
      _id: 
        date: 
          $dateToString: 
            format: "%m-%Y",
            date: "$reviewUpdatedAt"
          
        ,
        loc: "$branchId"
      ,
      Total: 
        $sum: 1
      
    
  ,
  
    $group: 
      _id: "$_id.loc",
      reviews: 
        $push: 
          Total: "$Total",
          "date": "$_id.date"
        
      
    
  
])

测试: MongoDB-Playground

【讨论】:

这很好用!但是,是否可以插入一个没有结果的月份的条目?例如,假设我的 $match 的日期范围是 01-2019 到 12-2019。我想要该月的所有 12 个条目,默认值为:0。这可能吗? @AndrewTaylor :我当然会给出我的答案,但这有点棘手,你能提出一个新问题吗没有这样做,或者同时我这样做了.. ***.com/questions/60571986/… @AndrewTaylor :您是否有机会从 2018 年的一个月开始并在 2019 年的一个月结束。像 :: 08-2018 到 09-2019 ? (或者只是针对特定年份,例如 01-2019 到 12-2019)? 是的,从技术上讲,查询可以是任何时间范围/月份。但是,默认情况下,它将在每个月的 1 日运行,并采用当前日期并返回 12 个月。

以上是关于MongoDB聚合查询返回集合中每年每月的条目总数,按位置值分组的主要内容,如果未能解决你的问题,请参考以下文章

猫鼬日期比较没有时间和按createdAt和staffId分组,每周、每月和每年按聚合计算的员工总数?

MongoDB shell 3 集合方法

MongoDB shell 0 集合方法

Mongodb聚合查询$match和$group

MongoDB——聚合管道之$group操作

MongoDB——聚合管道之$group操作