'Aggregation from MongoDB to Spring Boot Aggregation Framework

I am new to Spring And Mongo. I am using Spring Batch for getting some reports. My Query needs some aggregation which is not supported by MongoItemReader so I extended that class as per below stackoverflow link.

How to use Aggregation Query with MongoItemReader in spring batch

But there is something wrong with my Aggregation. I made aggregation which works fine in mongoDB but not able to convert it into Spring mongo aggregation.

MongoDb Aggregation which works as expected.

db.getCollection('orders').aggregate([
  {$match: {orderDate: {$gt:"2021-03-15",$lt: "2021-03-17"}, "status" :{"$in": ["GREEN", "YELLOW"]}}},
  {$group: {_id: {orderDate: "$orderDate", node: "$node", code1:"$code1", code2:"$code2"}, orderUnts: {$sum: 1}}},
  {"$project": {orderDate:"$_id.orderDate", node:"$_id.node", code1:"$_id.code1", code2:"$_id.code2", orderUnts:"$orderUnts"}}
])

Spring Mongo Aggregation which gives error.

String[] fields = {"orderDate", "node", "code1", "code2"};
String[] projectionFields = {"orderDate", "orderDate", "code1", "code2"};
MatchOperation matchOp = Aggregation.match(Criteria.where("orderDate").gt(startDate).and("orderDate").lt(endDate).and("status").in("GREEN", "YELLOW"));
GroupOperation groupOp = Aggregation.group(fields).sum("orderUnts").as("_id");
ProjectionOperation projectOp = Aggregation.project(projectionFields);
SortOperation sortOp = Aggregation.sort(Sort.by(Sort.Direction.ASC, "orderDate"));
Aggregation aggregation = Aggregation.newAggregation(matchOp, groupOp, projectOp, sortOp);

I am getting below unique field error.

Caused by: java.lang.IllegalStateException: An implementation of MongoOperations is required.
at org.springframework.util.Assert.state(Assert.java:76)
at org.springframework.batch.item.data.MongoItemReader.afterPropertiesSet(MongoItemReader.java:238)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1847)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1784)
... 81 common frames omitted

MongoItemReader extended class.

@Data
public class CustomMongoItemReader<T> extends MongoItemReader<T> {

    private MongoTemplate template;
    private Class<? extends T> type;
    private String collection;
    private MatchOperation matchOperation;
    private GroupOperation groupOperation;
    private ProjectionOperation projectionOperation;
    private SortOperation sortOperation;
    private Aggregation aggregation;

    @Override
    protected Iterator<T> doPageRead() {
        Pageable page = PageRequest.of(this.page, this.pageSize);
        if(matchOperation != null && groupOperation != null) {
            Aggregation agg = Aggregation.newAggregation(matchOperation,
                    groupOperation,
                    projectionOperation,
                    sortOperation,
                    Aggregation.skip(Long.valueOf(page.getPageNumber() * page.getPageSize())),
                    Aggregation.limit(page.getPageSize())
            );
            return (Iterator<T>) template.aggregate(agg, collection, this.type).iterator();
        }
        else {
            return Collections.emptyIterator();
        }
    }
}

Let me know if question needs more info. Thanks in Advance.



Solution 1:[1]

java.lang.IllegalStateException: An implementation of MongoOperations is required.

Your item reader extends MongoItemReader which requires a MongoOperations (typically a MongoTemplate). This error means that your item reader was not configured with a MongoOperations.

You need to set one on the reader before using it.

Solution 2:[2]

Also override with afterPropertiesSet() throws Exception{} with properties which are required for aggregation, for Reference check MongoItemReader<T>.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mahmoud Ben Hassine
Solution 2 Tyler2P