Reputation: 73
I've been scratching my head how to aggragate data in a way where I can use it further down the application.
What im trying to do is get the raw
{
"_id" : ObjectId("61e0898effba6778d05827e0"),
"customId" : {
"_id" : UUID("315fa023-f6a4-4d34-865c-dbe661e46cd1")
},
"viewers" : 1,
"auditTime" : ISODate("2022-01-13T20:20:30.880Z"),
}
* lots
Into
{
"customId" : {
"_id" : UUID("315fa023-f6a4-4d34-865c-dbe661e46cd1")
},
"averageViewers" : 5,
"timePeriod" : ISODate("2022-01-13T20:10:00.00Z"),
}
I've got the matching down for time periods
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);
I think the idea solution would be to use the mongo atlas aggragations which i think will be easy once this is fixed.
But im a loss. Any tips or tricks will be super appreciated
Thanks Adam
Upvotes: 1
Views: 357
Reputation: 2002
Some improvement user DateTrunc no need to project a second time:
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");
Upvotes: 0
Reputation: 73
@indybee
This worked with a little fiddling.
I changed count to average to get the average per hour (sorry dodgy question)
And used the DateOperator to pull Year Month day hour out of it
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");
....
Thank you!
Upvotes: 1
Reputation: 1736
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();
Upvotes: 1