【问题标题】:Group by time interval spring-data-mongo按时间间隔分组 spring-data-mongo
【发布时间】:2019-02-07 21:58:31
【问题描述】:

以下是我的文档结构:

{
   "_id":"5c59c35d8610f702d00e6f70",
   "stationId":"2",
   "listenerId":"807",
   "streamId":"37",
   "userAgentId":"7",
   "botDefinitionId":"18",
   "ipAddress":"50.116.14.48",
   "startTime":"2018-02-06T12:51:59.000Z",
   "endTime":"2018-02-06T12:53:56.000Z",
   "listenLength":"117",
   "totalDataUsed":"1433582",
}

使用 spring 数据 mongo,我想将它们分组到时间窗口中(比如说 15 分钟间隔)。我创建了以下工作查询:

{
   '_id':{
      'year':{
         '$year':'$startTime'
      },
      'week':{
         '$week':'$startTime'
      },
      'dayOfMonth':{
         '$dayOfMonth':'$startTime'
      },
      'month':{
         '$month':'$startTime'
      },
      'hour':{
         '$hour':'$startTime'
      },
      'interval':{
         '$subtract':[
            {
               '$minute':'$startTime'
            },
            {
               '$mod':[
                  {
                     '$minute':'$startTime'
                  },
                  15
               ]
            }
         ]
      }
   },
   'count':{
      '$sum':1
   }
}

然后返回给我以下文件:

_id:{
   year:2018   week:15   dayOfMonth:18   month:4   hour:18   interval:45
},
count:9

如何在 spring-data-mongo 中使用 GroupOperation 来指定这个聚合?

【问题讨论】:

    标签: mongodb spring-data-mongodb


    【解决方案1】:

    我能想到的一种方法是在 $project 阶段调用函数,而不是在 $group 阶段调用它们。

    使用DateOperator 类提取小时、分钟、年份等字段。 然后将SpEL andExpression 用作间隔字段:

    andExpression("minute - minute % 15").as("interval")
    

    这将使用小时、间隔、年份等字段重塑您的文档。然后将它们按间隔和您想要的其他字段分组。

    Aggregation agg = Aggregation.newAggregation(
    
        Aggregation.project()
            .and(DateOperators.Minute.minute("$timestamp")).as("minute")
            .and(DateOperators.Hour.hour("$timestamp")).as("hour")
            .and(DateOperators.DayOfMonth.dayOfMonth("$timestamp")).as("dayOfMonth"),
    
        Aggregation.project("hour","dayOfMonth","minute")
            .andExpression("minute - minute % 15").as("interval"),
    
        Aggregation.group("hour","dayOfMonth","interval")
            .addToSet("hour").as("hour")
            .addToSet("dayOfMonth").as("dayOfMonth")
            .addToSet("interval").as("interval")
            .count().as("count")
    );
    
    List<QueryResult> result = mongoTemplate.aggregate(agg, "collection_name", QueryResult.class).getMappedResults();
    

    【讨论】:

      猜你喜欢
      • 2011-12-20
      • 2011-02-08
      • 2019-06-28
      • 2018-10-12
      • 2016-09-21
      • 2017-09-06
      • 2021-03-06
      • 2016-10-06
      相关资源
      最近更新 更多