'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 |
