更多的聚合操作与计算操作文档地址:
中文文档:https://docs.mongoing.com/can-kao/yun-suan-fu/aggregation-pipeline-operators
英文文档:https://www.mongodb.com/docs/manual/reference/operator/aggregation
https://www.mongodb.com/docs/manual/core/aggregation-pipeline/
db.orders.insertMany( [
{ _id: 0, name: "Pepperoni", size: "small", price: 19,
quantity: 10, date: ISODate( "2021-03-13T08:14:30Z" ) },
{ _id: 1, name: "Pepperoni", size: "medium", price: 20,
quantity: 20, date : ISODate( "2021-03-13T09:13:24Z" ) },
{ _id: 2, name: "Pepperoni", size: "large", price: 21,
quantity: 30, date : ISODate( "2021-03-17T09:22:12Z" ) },
{ _id: 3, name: "Cheese", size: "small", price: 12,
quantity: 15, date : ISODate( "2021-03-13T11:21:39.736Z" ) },
{ _id: 4, name: "Cheese", size: "medium", price: 13,
quantity:50, date : ISODate( "2022-01-12T21:23:13.331Z" ) },
{ _id: 5, name: "Cheese", size: "large", price: 14,
quantity: 10, date : ISODate( "2022-01-12T05:08:13Z" ) },
{ _id: 6, name: "Vegan", size: "small", price: 17,
quantity: 10, date : ISODate( "2021-01-13T05:08:13Z" ) },
{ _id: 7, name: "Vegan", size: "medium", price: 18,
quantity: 10, date : ISODate( "2021-01-13T05:10:13Z" ) }
] )
select name as id,sum(quantity)
from orders
where size = 'medium'
group by name
db.orders.aggregate( [
// Stage 1: Filter pizza order documents by pizza size
{
$match: { size: "medium" }
},
// Stage 2: Group remaining documents by pizza name and calculate total quantity
{
$group: { _id: "$name", totalQuantity: { $sum: "$quantity" } }
}
] )
@Test
public void aggregation1(){
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.match(new Criteria().and("size").is("medium")),
Aggregation.group("id").first("id").as("id")
.sum("quantity").as("totalQuantity")
);
AggregationResults<OrdersEntity> aggregate = mongoTemplate.aggregate(aggregation, Orders.class, OrdersEntity.class);
for (OrdersEntity ordersEntity : aggregate) {
System.out.println(ordersEntity);
}
}
SELECT
a.id,
a.totalOrderValue,
a.averageOrderQuantity
FROM (
SELECT
DATE_FORMAT( date, '%Y-%m-%d' ) AS id,
sum( price * quantity ) as totalOrderValue,
avg( quantity ) as averageOrderQuantity
FROM
orders
WHERE 1=1
AND date >= "2020-01-30"
AND date <= "2022-01-30"
GROUP BY
DATE_FORMAT( date, '%Y-%m-%d' )
) a
ORDER BY a.totalOrderValue
db.orders.aggregate( [
// Stage 1: Filter pizza order documents by date range
{
$match:
{
"date": { $gte: new ISODate( "2020-01-30" ), $lt: new ISODate( "2022-01-30" ) }
}
},
// Stage 2: Group remaining documents by date and calculate results
{
$group:
{
_id: { $dateToString: { format: "%Y-%m-%d", date: "$date" } },
totalOrderValue: { $sum: { $multiply: [ "$price", "$quantity" ] } },
averageOrderQuantity: { $avg: "$quantity" }
}
},
// Stage 3: Sort documents by totalOrderValue in descending order
{
$sort: { totalOrderValue: -1 }
}
] )
@Test
public void aggregation2(){
Calendar from = Calendar.getInstance();
from.set(2020,Calendar.JANUARY,30);
Calendar to = Calendar.getInstance();
to.set(2022,Calendar.JANUARY,30);
Criteria criteria = new Criteria();
criteria.andOperator(Criteria.where("date").gte(from.getTime()).lte(to.getTime()));
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.match(criteria),
Aggregation.project("date","quantity")
.andExpression("{$dateToString:{format:'%Y-%m-%d',date:'$date'}}").as("id")
.andExpression("{$multiply:{'$price','$quantity'}}").as("priceMultiQuantity"),
Aggregation.group("id")
.sum("priceMultiQuantity").as("totalOrderValue")
.avg("quantity").as("averageOrderQuantity"),
Aggregation.sort(Sort.by(Sort.Direction.DESC,"totalOrderValue"))
);
AggregationResults<OrdersEntity> aggregate = mongoTemplate.aggregate(aggregation, Orders.class, OrdersEntity.class);
for (OrdersEntity ordersEntity : aggregate) {
System.out.println(ordersEntity);
}
}