0

This is my JSON.

{
    "_id" : ObjectId("5c7a590350d039fdc86e4e37"),
    "cropData" : {
        "cropName" : "RICE",
        "crop" : "RICE",
        "cropAcres" : 10.0,
        "cropYield" : 73.0,
        "cropPrice" : 3619.0
    },
    "creationTime" : "1551521509975",
    "villageId" : "581edb59e4b0b5b1ebbfe757"
}

There are 1000 entries like this in Collection called FarmerCropDataLog. I want to get highest and average values from this FarmerCropDataLog for particular village. for this I wrote following code.

public void getSheet(GetComparisonSheetRequest getComparisonSheet, BasicResponse response,String requestFarmerId) {

            Farmer farmer = this.getFarmerById(requestFarmerId);

            //  get logs before this year..
            String villageId = farmer.getVillageId();

            MatchOperation matchOperation = Aggregation.match(Criteria.where(FarmerCropDataLog.Constants.CROP_LOG).elemMatch(Criteria.where(CropData.Constants.CROP).is(getComparisonSheet.getCrop()))
                                    .andOperator(Criteria.where(FarmerCropDataLog.Constants.VILLAGE_ID).is(villageId))
                                    .andOperator(Criteria.where(FarmerCropDataLog.Constants.CREATION_TIME).gt(LAST_YEAR)));

            GroupOperation groupOperation  = Aggregation.group(FarmerCropDataLog.Constants.VILLAGE_ID);
            groupOperation.avg(CropData.Constants.CROP_PRICE).as("averageIncome");
            groupOperation.max(CropData.Constants.CROP_PRICE).as("maxIncome");

            Aggregation aggregation = Aggregation.newAggregation(matchOperation,groupOperation);
            AggregationResults<GetComparisonSheetResponse> aggregationResults = farmerCropDataLogDAO.runAggregation(aggregation,FarmerCropDataLog.class,GetComparisonSheetResponse.class);  
            List<GetComparisonSheetResponse> getResult = aggregationResults.getMappedResults();

            GetComparisonSheetResponse comparisonSheetResponse = getResult.get(0);
            response.setResponse(comparisonSheetResponse);
            response.setSuccess(true);
        }

I am getting error, when I try to run farmerCropDataLogDAO.runAggregation. it throws exception, how can I run this successfully?

Exception Thrown :

Due to limitations of the com.mongodb.BasicDBObject, you can't add a second '$and' expression specified as '$and : [ { "creationTime" : { "$gt" : 1471228928}}]'. Criteria already contains '$and : [ { "villageId" : "5b0ed0bc77c8ae9704f65c43"}]'.
Avi Patel
  • 475
  • 6
  • 23
  • And the exception is? You should provide any errors returned because it gives people context. – Neil Lunn Mar 02 '19 at 10:54
  • It throws the exception which just prints internal error. – Avi Patel Mar 02 '19 at 10:55
  • You are being asked to actually show any returned errors in your question. Please do so. – Neil Lunn Mar 02 '19 at 10:56
  • @NeilLunn, added . – Avi Patel Mar 02 '19 at 10:58
  • 2
    There you go, "context"! Modern API releases ( as in the past 4 years ) use `Document` instead of `BasicDBObject`. Which version of spring mongo is this? Are you following an old tutorial written many years ago? Have you tried updating the spring-mongodb dependencies in your project? – Neil Lunn Mar 02 '19 at 11:00
  • Yes it's old documents. I have replaced one of the andOperators with in. is in operator replacement for andOperator? Because it started working. – Avi Patel Mar 02 '19 at 11:01
  • Aside from that, you don't need `andOperator()` here multiple times. You can simply chain `and` expressions of a single `Criteria`. – Neil Lunn Mar 02 '19 at 11:02
  • How, can you show me? – Avi Patel Mar 02 '19 at 11:02
  • Okay was just typing a short example but you appear to have it. In case it helps, [here's something with similar multiple AND statements inside an `$elemMatch`](https://stackoverflow.com/a/44473095/2313887), just like yours – Neil Lunn Mar 02 '19 at 11:11

1 Answers1

2

Okay, so i have changed my problem by changing code as suggested by @Neil, thanks to him.

I have changed this code from this

MatchOperation matchOperation = Aggregation.match(Criteria.where(FarmerCropDataLog.Constants.CROP_LOG).elemMatch(Criteria.where(CropData.Constants.CROP).is(getComparisonSheet.getCrop()))
                                    .andOperator(Criteria.where(FarmerCropDataLog.Constants.VILLAGE_ID).is(villageId))
                                    .andOperator(Criteria.where(FarmerCropDataLog.Constants.CREATION_TIME).gt(LAST_YEAR)));

to this ->

MatchOperation matchOperation = Aggregation.match(Criteria.where(FarmerCropDataLog.Constants.CROP_LOG).elemMatch(Criteria.where(CropData.Constants.CROP).is(getComparisonSheet.getCrop())
                    .and(FarmerCropDataLog.Constants.VILLAGE_ID).is(villageId)
                    .and(FarmerCropDataLog.Constants.CREATION_TIME).gt(LAST_YEAR)));
Avi Patel
  • 475
  • 6
  • 23