【问题标题】:Spring Mongo aggragation average per hourSpring Mongo 每小时聚合平均值
【发布时间】:2022-01-18 10:49:16
【问题描述】:

我一直在摸索如何以一种可以在应用程序中进一步使用的方式聚合数据。

我想做的是得到原始的

{
    "_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 聚合,我认为一旦解决这个问题就会很容易。

但我很茫然。任何提示或技巧将不胜感激

谢谢 亚当

【问题讨论】:

  • timePeriod 是否总是准时(从您的问题标题)?我基于此发布了一个可能的答案

标签: spring mongodb spring-boot aggregate


【解决方案1】:
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();

【讨论】:

    【解决方案2】:

    @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");
    
     ....
    
    

    谢谢!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多