Reputation: 149
how to calculate average of a field in mongoDB and spring. we have $avg() function for terminal use but how to execute it with mongotemplate.
for example in
db.sales.aggregate(
[
{
$group:
{
_id: "$item",
avgAmount: { $avg: { $multiply: [ "$price", "$quantity" ] } },
avgQuantity: { $avg: "$quantity" }
}
}
]
)
we are calculating average here so how can we execute it with mongotemplate.
Now I am using a function to get average rating
i am using function like this..
public List getrating() {
TypedAggregation<RatingReviewModel> agg = newAggregation(RatingReviewModel.class,
group("hospitalid")
.avg("rating").as("avgrating")
);
AggregationResults<DBObject> result = operations.aggregate(agg, DBObject.class);
List<DBObject> resultList = result.getMappedResults();
return resultList;
}
but at the time of debugging resultList is Empty so it is returning nothing.
Upvotes: 2
Views: 4811
Reputation: 103365
Suppose your Sale object is defined as:
class Sale {
String id;
String item;
double price;
int quantity;
}
Using the mongotemplate you would need a $project
stage in the pipeline before hand to get the calculated fields, which can be a bit counter-intuitive because with the native MongoDB aggregation all is done in one $group
operation pipeline rather than splitting the aggregation into two stages, thus:
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
TypedAggregation<Sale> agg = newAggregation(Sale.class,
project("quantity")
.andExpression("price * quantity").as("totalAmount"),
group("item")
.avg("totalAmount").as("avgAmount")
.avg("quantity").as("avgQuantity")
);
AggregationResults<DBObject> result = mongoTemplate.aggregate(agg, DBObject.class);
List<DBObject> resultList = result.getMappedResults();
The above can also be achieved using the native Java Driver implementation:
ApplicationContext context = new AnnotationConfigApplicationContext(SpringMongoConfig.class);
MongoOperations operation = (MongoOperations) context.getBean("mongoTemplate");
BasicDBList pipeline = new BasicDBList();
String[] multiplier = { "$price", "$quantity" };
pipeline.add(
new BasicDBObject("$group",
new BasicDBObject("_id", "$item")
.append("avgAmount", new BasicDBObject(
"$avg", new BasicDBObject(
"$multiply", multiplier
)
))
.append("avgQuantity", new BasicDBObject("$avg", "$quantity"))
)
);
BasicDBObject aggregation = new BasicDBObject("aggregate", "sales")
.append("pipeline", pipeline);
System.out.println(aggregation);
CommandResult commandResult = operation.executeCommand(aggregation);
Upvotes: 2