【问题标题】:Spring Data mongodb aggregation framework: ConditionalOperators in project() for median calculationSpring Data mongodb聚合框架:project()中的ConditionalOperators进行中位数计算
【发布时间】:2018-09-25 05:22:32
【问题描述】:

在使用 Spring Data 2.0 的示例项目中,我试图计算具有以下格式的文档的温度中值:

{  
   "_id":ObjectId("5ad28e92e284e00bbc0a9479"),
   "deviceId":"myId",
   "time":   ISODate("2018-04-21T23:28:18.632   Z"),
   "temperature":10,
   "_class":"com.github.paizo.monitorapi.model.Refrigerator"
}

here 我抓取一个聚合管道来计算我转换为以下 Spring Data 聚合的中值:

final Aggregation aggregation = newAggregation(
        match(
                Criteria.where(DEVICE_ID_FIELD).is(deviceId)
        ),
        group().count().as("count").push(sensorValueField).as("values"),
        unwind("values"),
        sort(Sort.Direction.ASC, "values"),
        project("count", "values")
                .andExpression("(count) / 2").as("midpoint"),
        project("count", "values", "midpoint")
                .and(floor).as("low")
                .and(ceil).as("high"),
        group()
                .push("values").as("values")
                .avg("high").as("high")
                .avg("low").as("low"),
        project()
                .and(beginValue).as("beginValue")
                .and(endValue).as("endValue"),
        //FIXME if ODD => v1 == v2 then return v1 else v1 != v2 => return average(v1,v2)
        project().and(
                ConditionalOperators.when(Criteria.where("beginValue").ne("endValue"))
                    .then("beginValue")
                    .otherwiseValueOf("(beginValue + endValue) / 2")
        )
);

我试图在最后一个project() 中进行最终值检查的计算中可能出现的错误的一部分。 无论我在ConditionalOperators.when() 中写什么,生成的项目都是空的

{  
   "aggregate":"refrigerator",
   "pipeline":[  
      {  
         "$match":{  
            "deviceId":"myId"
         }
      },
      {  
         "$group":{  
            "_id":null,
            "count":{  
               "$sum":1
            },
            "values":{  
               "$push":"$temperature"
            }
         }
      },
      {  
         "$unwind":"$values"
      },
      {  
         "$sort":{  
            "values":1
         }
      },
      {  
         "$project":{  
            "count":1,
            "values":1,
            "midpoint":{  
               "$divide":[  
                  "$count",
                  2
               ]
            }
         }
      },
      {  
         "$project":{  
            "count":1,
            "values":1,
            "midpoint":1,
            "low":{  
               "$floor":"$midpoint"
            },
            "high":{  
               "$ceil":"$midpoint"
            }
         }
      },
      {  
         "$group":{  
            "_id":null,
            "values":{  
               "$push":"$values"
            },
            "high":{  
               "$avg":"$high"
            },
            "low":{  
               "$avg":"$low"
            }
         }
      },
      {  
         "$project":{  
            "beginValue":{  
               "$arrayElemAt":[  
                  "$values",
                  "$low"
               ]
            },
            "endValue":{  
               "$arrayElemAt":[  
                  "$values",
                  "$high"
               ]
            }
         }
      },
      {  
         "$project":{  

         }
      }
   ],
   "cursor":{  
      "batchSize":2147483647
   }
}

导致错误的原因:

org.springframework.data.mongodb.UncategorizedMongoDbException: Command failed with error 40177: 'Invalid $project :: caused by :: specification must have at least one field' on server localhost:27017. The full response is { "ok" : 0.0, "errmsg" : "Invalid $project :: caused by :: specification must have at least one field", "code" : 40177, "codeName" : "Location40177" }; nested exception is com.mongodb.MongoCommandException: Command failed with error 40177: 'Invalid $project :: caused by :: specification must have at least one field' on server localhost:27017. The full response is { "ok" : 0.0, "errmsg" : "Invalid $project :: caused by :: specification must have at least one field", "code" : 40177, "codeName" : "Location40177" }

我对最后一个project() 做错了什么?是 Spring 数据问题吗?

【问题讨论】:

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


    【解决方案1】:

    回答我自己的问题,也许它可以帮助别人。

    原来$project没有生成是因为project.and(...)后面缺少as()

    以下示例为条件运算符正确生成$project

                project().and(ConditionalOperators.when(Criteria.where("beginValue").ne("endValue"))
                        .then("beginValue")
                        .otherwiseValueOf("(beginValue + endValue) / 2")).as("lowViewsQuestion")
    

    【讨论】:

      猜你喜欢
      • 2013-12-25
      • 2014-05-11
      • 1970-01-01
      • 2018-01-16
      • 1970-01-01
      • 2012-10-25
      • 1970-01-01
      • 1970-01-01
      • 2020-11-13
      相关资源
      最近更新 更多