1

Following code doesn't give the expected results, i've tried with multiple documents, those documents structured as follows.

_id: 5a7714d44c75220958e6aa01
imei:355227045347655
point: [3.143453333333333,80.10954]
heading: 0
speed:0
timestamp: 2018-02-04 19:42:36.000
point_distance: 525.25

Now i need to calculate sum of point_distance of every record match with given imei and time period. I've tried to achieve this with following code but returns nothing even if required data exists.

public Object findDistance(long imei, Date from, Date to) {
    List aggregationOps = new ArrayList<>();
    //operations
    aggregationOps.add(match(Criteria.where("imei").is(imei)));
    aggregationOps.add(match(Criteria.where("timestamp").gte(from)));
    aggregationOps.add(match(Criteria.where("timestamp").lte(to)));
    aggregationOps.add(group("imei").sum("point_distance").as("distance"));
    aggregationOps.add(project("imei").and("distance").previousOperation());

    AggregationOptions agOps = new AggregationOptions.Builder().allowDiskUse(true).cursor(new BasicDBObject()).build();

    return (DistanceInfo) getMongoTemplate()
            .aggregate(newAggregation(aggregationOps).withOptions(agOps), Location.class, DistanceInfo.class)
            .getUniqueMappedResult();
}

Date > from and to are formatted as yyyy-MM-dd hh:mm:ss

DistanceInfo class

public class DistanceInfo {
    long imei;
    double distance;
}

I'm new to this mongodb stuff and no idea what did i do wrong, how can i correct this ? any help is much appreciated.

benjamin c
  • 2,278
  • 15
  • 25

1 Answers1

2

Try this. this should work

MatchOperation matchOperation = match(Criteria.where("imei").is(imei) 
     .and("timestamp").gte(from.getTime()).lte(to.getTime()));

GroupOperation groupOperation = group("imei").sum("point_distance").as("distance");
ProjectionOperation projectionOperation = project().andExpression("imei").as("imei")
    .andExpression("distance").as("distance");

Aggregation aggregation = newAggregation(matchOperation, groupOperation, projectionOperation);
AggregationResults<DistanceInfo> results = mongoTemplate.aggregate(aggregation, "location", DistanceInfo.class);

return  results.getMappedResults();
pvpkiran
  • 25,582
  • 8
  • 87
  • 134
  • It returns an error `Command failed with error 9: 'The 'cursor' option is required, except for aggregate with the explain argument'` – benjamin c Feb 04 '18 at 18:39
  • I'm using `mongodb-java-driver 3.6.1` and `spring-data-mongodb 1.10.9` – benjamin c Feb 04 '18 at 18:41
  • On my machine it works. I am using mongodb-driver 3.4.3 and spring-data-mongodb 1.10.8.RELEASE. https://stackoverflow.com/questions/47472688/spring-data-mongodb-the-cursor-option-is-required – pvpkiran Feb 04 '18 at 19:03
  • Try removing `.cursor(new BasicDBObject())` this code in your originial code – pvpkiran Feb 04 '18 at 21:53
  • so, i had to upgrade `spring-data` version to `1.10.10.RELEASE` and used this solution, it worked, removing `.cursor(new BasicDBObject())` didn't worked though, thank you for helping. – benjamin c Feb 05 '18 at 14:17