mongodb - 按时间间隔分组 spring-data-mongo
问题描述
以下是我的文档结构:
{
"_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 data 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
如何使用GroupOperation在 spring-data-mongo 中指定此聚合?
解决方案
我能想到的一种方法是在 $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();