MongoDB - 组内组&&组和项目

Posted

技术标签:

【中文标题】MongoDB - 组内组&&组和项目【英文标题】:MongoDB - group inside group && group and project 【发布时间】:2020-04-09 12:55:09 【问题描述】:

我是一个新人,正在使用 Laravel 学习 MongoDB。

这是我的问题。

我需要在 60 天内获取记录并按类型分组。

在每个 type 组中,我必须按范围时间对它们进行分组:

60 - 30 天前 30 天前 - 现在

我研究了 2 天,这些是我目前的代码。

$collection->aggregate([
    [
        '$match' => $match,
    ],
    [
        '$project' => [
            'range' => [
                '$concat' => [
                    [
                        '$cond' => [
                            [
                                '$and' => [
                                    ['$gte' => ['$created_at', $ago_60_days]],
                                    ['$lte' => ['$created_at', $ago_30_days]],
                                ],
                            ],
                            'before',
                            '',
                        ],
                    ],
                    [
                        '$cond' => [
                            [
                                '$and' => [
                                    ['$gt' => ['$created_at', $ago_30_days]],
                                    ['$lte' => ['$created_at', $now]],
                                ],
                            ],
                            'current',
                            '',
                        ],
                    ],
                ],
            ],
        ],
    ],
    [
        '$group' => [
            '_id' => '$type,
            'total' => ['$sum' => 1],
        ],
    ],
    ... anything after ???
]);

请告诉我任何事情,任何线索都可以帮助我。

我可以使用 mongo shell

非常感谢你们。

【问题讨论】:

如果我发布 mongo shell(不是 laravel)的聚合代码,你能管理吗? @prasad_ 是的。我能应付。请让我知道你的决议。谢谢。 type是文档中的字段还是和“范围时间”一样吗? (我假设它是一个不同的领域)。 【参考方案1】:

查询:

db.test.aggregate( [
   
      $match:  
          $expr:  
              $gte:  [ "$dt",  $subtract: [ ISODate(), 60*24*60*60*1000 ]  ] 
           
       
  ,
   
      $addFields:  
          rangeTime:  
              $cond:  
                  if:  $gte: [ "$dt",  $subtract: [ ISODate(), 30*24*60*60*1000 ]  ] ,
                  then: "range_30_now",
                  else: "range_60_30"
               
           
      
  ,
  
      $group:  
          _id: 
              t: "$type", r: "$rangeTime" 
          , 
          total:  $sum: 1  
      
  ,
   
      $project:  
          type: "$_id.t", 
          rangeTime: "$_id.r", 
          total: 1, 
          _id: 0 
       
  ,
   
      $sort:  
          type: 1, 
          rangeTime: -1  
       
  
] )

输出:

 "total" : 2, "type" : "A", "rangeTime" : "range_60_30" 
 "total" : 1, "type" : "B", "rangeTime" : "range_60_30" 
 "total" : 2, "type" : "B", "rangeTime" : "range_30_now" 

输入文件:

 "_id" : 1, "dt" : ISODate("2019-10-15T00:00:00Z"), "type" : "A" 
 "_id" : 2, "dt" : ISODate("2019-10-20T00:00:00Z"), "type" : "B" 
 "_id" : 3, "dt" : ISODate("2019-11-08T00:00:00Z"), "type" : "A" 
 "_id" : 4, "dt" : ISODate("2019-11-29T00:00:00Z"), "type" : "B" 
 "_id" : 5, "dt" : ISODate("2019-11-15T00:00:00Z"), "type" : "A" 
 "_id" : 9, "dt" : ISODate("2019-12-15T00:00:00Z"), "type" : "B" 

【讨论】:

非常感谢。我正在尝试您的解决方案。

以上是关于MongoDB - 组内组&&组和项目的主要内容,如果未能解决你的问题,请参考以下文章

如何随机抽样删除一些组和随机删除组内的一些个人?

在转换组内仅触发一次事件

MongoDB聚合组和计数字符串

MongoDB $in && $all

MongoDB操作&&注入漏洞&&未授权访问漏洞

mongodb建立索引&查看索引&删除索引