0

I am trying to convert MongoDB Aggregation function to Java Aggregation function.

My MongoDB Query is

[
 {
   "$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"
     }
 }
]

I tried bellow code for conversion in 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)));

                }
            }



        );

I am getting problem with bellow line

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

And error as per bellow

 Invalid reference '$firstResult'!

Thanks in advance.

0

1 Answer 1

1

You can simplify your aggregation on 1.10.1-Release spring mongo version. You should avoid using BasicDBObject/Document and use spring provided helper methods.

 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)
 );
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.