【问题标题】:Dynamically multiple averages in one Aggregation Spring Boot一个聚合 Spring Boot 中的动态多个平均值
【发布时间】:2021-09-22 16:38:41
【问题描述】:

我一直在尝试使用 Spring Boot 聚合按标识符分组多个平均值。我想要其平均值的字段由参数给定的数组定义,但我无法检索多个平均值。 数据存储方式如下:

{
    "_id": {
        "$oid": "XX"
    },
    "space_id": "AA",
    "temperature": 50,
    "temperatureUoMCode": 0,
    "pm25": 50,
    "pm25UoMCode": 0,
    "co2": 0.0005,
    "co2UoMCode": 0,
    "co": 1,
    "coUoMCode": 0,
    "gas": 50,
    "gasUoMCode": 0,
    "humidity": 50,
    "humidityUoMCode": 0,
    "occupants": 6,
    "maxCapacity": 15,
    "_class": "Record"
}

我正在使用的代码:

List<AggregationOperation> aggregationOperations = new ArrayList<>();
        aggregationOperations.add(Aggregation.match(
                Criteria.where("space_id").is(space_id)
        ));
        for(Variable var : concerns){
            System.out.println(var.getField());
            aggregationOperations.add(Aggregation.group(
                            space_id).
                    avg(var.getField()).as(var.getAvg()));
        }
        Aggregation aggregation = Aggregation.newAggregation(
                aggregationOperations
        );
        AggregationResults<HashMap> results = mongoTemplate.aggregate(
                aggregation, "records",HashMap.class);

另外,Variable 类是一个枚举,有两个字段,db 中的字段名称(field)和平均别名(avg)。 当我运行它时,我得到以下输出:

co
pm25
temperature
humidity
gas
    2021-09-22 11:34:17.046 ERROR 42971 --- [a1-0b2af6e69097] TConfig$$EnhancerBySpringCGLIB$$673c396b : Invalid reference 'pm25'!
    java.lang.IllegalArgumentException: Invalid reference 'pm25'!
        at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:114)
        at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:86)
        at org.springframework.data.mongodb.core.aggregation.GroupOperation$Operation.getValue(GroupOperation.java:529)
        at org.springframework.data.mongodb.core.aggregation.GroupOperation$Operation.toDocument(GroupOperation.java:507)
        at org.springframework.data.mongodb.core.aggregation.GroupOperation.toDocument(GroupOperation.java:441)
        at org.springframework.data.mongodb.core.aggregation.AggregationOperation.toPipelineStages(AggregationOperation.java:55)
        at org.springframework.data.mongodb.core.aggregation.AggregationOperationRenderer.toDocument(AggregationOperationRenderer.java:56)
        at org.springframework.data.mongodb.core.aggregation.AggregationPipeline.toDocuments(AggregationPipeline.java:81)
        at org.springframework.data.mongodb.core.aggregation.Aggregation.toPipeline(Aggregation.java:716)
        at org.springframework.data.mongodb.core.AggregationUtil.createPipeline(AggregationUtil.java:112)
        at org.springframework.data.mongodb.core.MongoTemplate.doAggregate(MongoTemplate.java:2144)
        at org.springframework.data.mongodb.core.MongoTemplate.doAggregate(MongoTemplate.java:2119)
        at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:2113)
        at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:2014)
        at co.edu.javeriana.smartuj.EnvironmentalAlerts.services.AlertService.makeQuery(AlertService.java:131)

【问题讨论】:

    标签: spring-boot aggregation-framework spring-data-mongodb


    【解决方案1】:

    如果有人遇到类似问题,我设法通过关注this post's answer 解决了它。我意识到,与其创建各种 GroupOperations,不如只创建一个 GroupOperations,并通过将“as”函数的返回值保存在同一个对象中来使用它来存储所有操作:

     MatchOperation matchOperation = Aggregation.match(Criteria.where("space_id").is(space_id));
            GroupOperation groupOperation = null;
            for(Variable var : concerns){
                if (groupOperation == null){
                    groupOperation = Aggregation.group("space_id")
                            .avg(var.getField())
                            .as(var.getAvg());
                }else
                    groupOperation = groupOperation
                            .avg(var.getField())
                            .as(var.getAvg());
            }
            Aggregation aggregation = Aggregation.newAggregation(
                    matchOperation,
                    groupOperation
            );
            AggregationResults<HashMap> results = mongoTemplate.aggregate(
                    aggregation, "records",HashMap.class);
            return results.getUniqueMappedResult();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-12
      • 2019-05-05
      • 1970-01-01
      • 1970-01-01
      • 2015-11-13
      • 1970-01-01
      • 2021-08-12
      • 1970-01-01
      相关资源
      最近更新 更多