尝试将 mongoDB 聚合查询转换为 java 聚合查询

Trying to convert mongoDB aggregation query to java aggregation query

我正在尝试将 MongoDB 聚合函数转换为 Java 聚合函数。

我的 MongoDB 查询是

[
 {
   "$match": {
     "indicesId": "VUSSTAPNETFF"
   }
 },
 {
   "$unwind": "$dataSets"
 },
 {
  "$match": {
     "dataSets.date": {
       "$lte":  ISODate("2013-12-31T18:30:00.000Z"),
       "$gte":  ISODate("2008-12-31T18:30:00.000Z")
     }
   }
 },
 {
   "$group": {
     "_id": "$indicesId",
     "mean": {
       "$avg": "$dataSets.data"
     },
     "indices": {
       "$push": "$$ROOT"
     }
   }
 },
 {
   "$unwind": "$indices"
 },
 {
   "$project": {
     "_id": 1,
     "mean": 1,
     "firstResult": {
       "$multiply": [
         {
           "$subtract": [
             "$indices.dataSets.data",
             "$mean"
           ]
         },
         {
           "$subtract": [
             "$indices.dataSets.data",
             "$mean"
           ]
         }
       ]
     }
   }
 },
 {
    "$group":{
        "_id":"",
        "secondResult": {
          "$avg": "$firstResult"
        },
        "mean":{
            "$first": "$mean"
        }
    }
 },
 {
     "$project":{
         "data":{
            "$sqrt":"$secondResult"
         },
         "mean": "$mean"
     }
 }
]

我在 java.

中尝试了以下转换代码
 BasicDBList subtractDBList= new BasicDBList();
 subtractDBList.add("$indices.dataSets.data");
 subtractDBList.add("$mean");

 BasicDBList multiplyDBList= new BasicDBList();
 multiplyDBList.add(new BasicDBObject("$subtract",subtractDBList));
 multiplyDBList.add(new BasicDBObject("$subtract",subtractDBList));


 Aggregation meanAggregation= Aggregation.newAggregation(Aggregation.match(Criteria.where(IndicesUtil.INDICES_ID).is(indicesId)),
 Aggregation.unwind(IndicesUtil.PREFIX+IndicesUtil.DATA_SETS),
            Aggregation.match(Criteria.where(IndicesUtil.DATA_SETS_DATE).gte(startDate).lte(indicesDataSet.getDate())),
            Aggregation.group(IndicesUtil.INDICES_ID).avg(averageParameter).as(IndicesUtil.MEAN).push("$$ROOT").as("indices"),
            Aggregation.unwind(IndicesUtil.PREFIX+IndicesUtil.INDICES),

            new AggregationOperation() {

                @Override
                public DBObject toDBObject(AggregationOperationContext arg0) {
                    return new BasicDBObject("$project",
                            new BasicDBObject("_id",1).append("mean", IndicesUtil.PREFIX+IndicesUtil.MEAN).append("firstResult", 
                                    new BasicDBObject("$multiply",multiplyDBList)));


                }
            },
            Aggregation.group().avg("$firstResult").as("secondResult").first(IndicesUtil.PREFIX+IndicesUtil.MEAN).as(IndicesUtil.MEAN),
            new AggregationOperation() {

                @Override
                public DBObject toDBObject(AggregationOperationContext arg0) {
                    return new BasicDBObject("$project",
                            new BasicDBObject(IndicesUtil.DATA,
                                    new BasicDBObject("$sqrt","$secondResult").append("mean", IndicesUtil.PREFIX+IndicesUtil.MEAN)));

                }
            }



        );

我遇到了波纹管问题

 Aggregation.group().avg("$firstResult").as("secondResult").first(IndicesUtil.PREFIX+IndicesUtil.MEAN).as(IndicesUtil.MEAN),

错误如下

 Invalid reference '$firstResult'!

提前致谢。

您可以在 1.10.1-Release spring mongo 版本上简化聚合。您应该避免使用 BasicDBObject/Document 并使用 spring 提供的辅助方法。

 Aggregation meanAggregation = Aggregation.newAggregation(
            Aggregation.match(Criteria.where(IndicesUtil.INDICES_ID).is(indicesId)),
            Aggregation.unwind(IndicesUtil.PREFIX+IndicesUtil.DATA_SETS),
            Aggregation.match(Criteria.where(IndicesUtil.DATA_SETS_DATE).gte(startDate).lte(indicesDataSet.getDate())),
            Aggregation.group(IndicesUtil.INDICES_ID).avg(averageParameter).as(IndicesUtil.MEAN).push("$$ROOT").as("indices"),
            Aggregation.unwind(IndicesUtil.PREFIX+IndicesUtil.INDICES),
            Aggregation.project("_id", "mean").andExpression("(indices.dataSets.data - mean) * (indices.dataSets.data - mean)").as("firstResult"),
            Aggregation.group().avg("$firstResult").as("secondResult").first(IndicesUtil.PREFIX+IndicesUtil.MEAN).as(IndicesUtil.MEAN),
            Aggregation.project("mean").and("secondResult").sqrt().as(IndicesUtil.DATA)
 );