我一直在摸索如何以一种可以在应用程序中进一步使用它的方式聚合数据。
我想做的是获取原始数据
{
"_id" : ObjectId("61e0898effba6778d05827e0"),
"customId" : {
"_id" : UUID("315fa023-f6a4-4d34-865c-dbe661e46cd1")
},
"viewers" : 1,
"auditTime" : ISODate("2022-01-13T20:20:30.880Z"),
}
* lots
进入
{
"customId" : {
"_id" : UUID("315fa023-f6a4-4d34-865c-dbe661e46cd1")
},
"averageViewers" : 5,
"timePeriod" : ISODate("2022-01-13T20:10:00.00Z"),
}
我已经记录了时间段的匹配情况
TypedAggregation<HistoricEntity> agg =
Aggregation.newAggregation(HistoricEntity.class,
Aggregation.match(Criteria.where("customId").is(channelId)),
Aggregation.match(Criteria.where("auditTime").gte(start).andOperator(Criteria.where("auditTime").lte(end))),
Aggregation.group("auditTime").avg("viewers").as("viewers")
);
AggregationResults<Map> aggregate = mongoTemplate.aggregate(agg, Map.class);
我认为理想的解决方案是使用 mongo atlas 聚合,我认为一旦解决这个问题就会很容易。
但我很失败。任何提示或技巧将非常感激
谢谢 亚当
ProjectionOperation convertAuditTimeToHourOp = Aggregation.project("customId", "viewers", "auditTime")
.and(StringOperators.Substr.valueOf("auditTime").substring(0, 13))
.as("auditHour");
GroupOperation countOp = Aggregation.group("customId", "auditHour").count().as("averageViewers");
ProjectionOperation convertAuditHourToDateOp = Aggregation.project("customId", "averageViewers", "auditHour")
.and(StringOperators.Concat.valueOf("auditHour").concat(":00:00.000Z")).as("timePeriodString");
ProjectionOperation convertTimePeriodToDate = Aggregation.project("customId", "averageViewers", "timePeriodString")
.and(DateFromString.fromStringOf("timePeriodString"))
.as("timePeriod");
AggregationResults<Document> aggregate = mongoTemplate.aggregate(
Aggregation.newAggregation(convertAuditTimeToHourOp, countOp, convertAuditHourToDateOp, convertTimePeriodToDate),
HistoricEntity.class,
Document.class
);
List<Document> mappedResults = aggregate.getMappedResults();
@indybee
这需要一点点摆弄。
我将计数更改为平均值以获得每小时的平均值(抱歉,这是一个狡猾的问题)
并使用 DateOperator 从中提取年月日小时
ProjectionOperation convertAuditTimeToHourOp = Aggregation.project("channelId", "viewers", "auditTime")
.and(DateOperators.dateOf("auditTime").toString("%Y-%m-%d-%H"))
.as("auditHour");
GroupOperation averageViewers = Aggregation.group("customId", "auditHour").avg("viewers").as("averageViewers");
ProjectionOperation convertTimePeriodToDate = Aggregation.project("customId", "averageViewers", "auditHour")
.and(DateOperators.DateFromString.fromStringOf("auditHour"))
.as("timePeriod");
....
谢谢!
一些改进用户DateTrunc无需再次投影:
ProjectionOperation convertAuditTimeToHourOp = Aggregation.project("channelId", "viewers", "auditTime")
.and(DateOperators.dateOf("auditTime").truncate("auditHour"))
.as("auditHour");
GroupOperation averageViewers = Aggregation.group("customId", "auditHour")
.avg("viewers").as("averageViewers")
.first("auditHour").as("auditHour")
.first("customId").as("customId");