Get simple average from collection with Spring Data MongoDB

I need to get the average duration of all the iterations made. I have the entity entity that I explain below:

@Document(collection = IterationEntity.COLLECTION_NAME)
public class IterationEntity {

    public final static String COLLECTION_NAME = "iterations";

    @Id
    private ObjectId id;

    @Field("start_date")
    private Date startDate;

    @Field("finish_date")
    private Date finishDate;

    @Field("duration")
    private Long duration;

    @Field("total_tasks")
    private Integer totalTasks = 0;

    @Field("total_failed_tasks")
    private Integer totalFailedTasks = 0;

    @Field("total_comments")
    private Integer totalComments = 0;

    @Field("tasks")
    @DBRef
    @CascadeSave
    private Set<TaskEntity> tasks = new HashSet<>();

}

I have implemented a custom repository method to perform this operation but I get an error when I get the result.

@Override
    public Long getAvgDuration() {

        GroupOperation avgOperation = Aggregation.group()
            .sum("duration")
                .as("total_duration")
            .avg("total_duration")
                .as("avg_duration");

        Aggregation aggregation = newAggregation(IterationEntity.class, avgOperation);

        return mongoTemplate.aggregate(aggregation, IterationEntity.COLLECTION_NAME, Long.class).getUniqueMappedResult();

    }

When the method is executed I get this exception:

org.springframework.data.mapping.model.MappingException: No mapping metadata found for java.lang.Long

Thanks in advance.

Upvotes: 1

Views: 933

Answers (1)

Christoph Strobl
Christoph Strobl

Reputation: 6726

In order to map the aggregation result correctly it needs to be mapped to a domain type or simply the Document returned.
Something like below should do what you're looking for.

class AggResult {
  @Field("total_duration") Long duration;
  @Field("avg_duration") Double avgDuration;
}

return template
  .aggregate(aggregation, COLLECTION_NAME, AggResult.class)
  .getUniqueMappedResult()
  .getAvgDuration();

Upvotes: 1

Related Questions