BB-8
BB-8

Reputation: 45

Not able to calculate average with MongoDB

I wonder that I can't get calculate the average with Spring 5 and MongoDB.

In the database are 40 entries with this format

Result(id=5e4adeca9eab5f052e2ac239, date=2020-02-12, value=1.048097596376957)

I'm interested to get the date from t1 to t2 and the average of all matches.

The code which I wrote and ens in an NPE looks like this:

    MatchOperation filterDate = match(Criteria.where("date").gte(startWeek).lte(now));
    GroupOperation groupByValue = group("value").avg("value").as("averageValue");

    Aggregation aggregation = newAggregation(filterDate, groupByValue);
    AggregationResults<Document> result = mongoTemplate.aggregate(aggregation, "unknown", Document.class);

    Document document = result.getUniqueMappedResult();
    document.getDouble("averageValue");

When getDouble will be invoked a NPE happens. The matchCriteria is in my opinion correct. By the GroupOperation I have my doubts.

2020-02-17 19:43:22.661 DEBUG 10148 --- [nio-8080-exec-1] o.s.data.mongodb.core.MongoTemplate : Executing aggregation: [{ "$match" : { "date" : { "$gte" : { "$date" : 1581289200000}, "$lte" : { "$date" : 1581894000000}}}}, { "$group" : { "_id" : "$value", "averageValues" : { "$avg" : "$value"}}}] in collection unkown

import org.springframework.data.annotation.Id;


public class Result {

    @Id
    private String id;

    private LocalDate date;

    private Double value;

    public Result(LocalDate date, Double value) {
        this.date = date;
        this.value = value;
    }
}

I wonder about the grouping. It this necessary? And do I need a collection?

Upvotes: 1

Views: 737

Answers (1)

Valijon
Valijon

Reputation: 13103

To calculate avg, you need to $group similar records and use $avg operator.

In your case, you want calculate average of all matches, but I guess you don't have a field with the same value for all filtered matches. In this case, you may order MongoDB group by null to calculate average.

Change your Group stage to below:

GroupOperation groupByValue = group().avg("value").as("averageValue");

which will be translated to:

{ "$group" : { "_id" : null, "averageValues" : { "$avg" : "$value"}}

Upvotes: 1

Related Questions