$group进行分布查询操作 类似于在MySQL中的group by,但可以操作的内容更多
虽然使用 $group 操作可以很方便的处理数据,但是需要注意的是,所以的分组数据是无序的,并且都是在内存中操作完成,所有操作的时候,不能支持大数据量。
官方文档: $group (aggregation) — MongoDB Manual
语法为
{ $group: { _id: <expression>, <field1>: { <accumulator1> : <expression1> }, ... } }
准备测试数据
db.getCollection('sales').insertMany([ { "_id" : 1, "item" : "abc", "price" : 10, "quantity" : 2, "date" : ISODate("2014-03-01T08:00:00Z") }, { "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1, "date" : ISODate("2014-03-01T09:00:00Z") }, { "_id" : 3, "item" : "xyz", "price" : 5, "quantity" : 10, "date" : ISODate("2014-03-15T09:00:00Z") }, { "_id" : 4, "item" : "xyz", "price" : 5, "quantity" : 20, "date" : ISODate("2014-04-04T11:21:39.736Z") }, { "_id" : 5, "item" : "abc", "price" : 10, "quantity" : 10, "date" : ISODate("2014-04-04T21:23:13.331Z") } ]);
示例:按照 item 字段进行分组,统计每个 item 下面的文档个数
db.sales.aggregate({ $group: { _id: "$item", count: { $sum: 1 } } }) 结果 jkl 1 abc 2 xyz 2
//java代码 Aggregation aggregation = newAggregation( Aggregation.group("item").count().as("count") ); AggregationResults<BasicDBObject> sales = mongoTemplate.aggregate(aggregation, "sales", BasicDBObject.class); List<BasicDBObject> mappedResults = sales.getMappedResults(); 查询结果 [ { "_id": "xyz", "count": 2 }, { "_id": "abc", "count": 2 }, { "_id": "jkl", "count": 1 } ]
示例:按照 item 字段进行分组,统计每个 item 下面 price 的总数,quantity 的平均数
db.sales.aggregate({ $group: { _id: "$item", priceCount:{$sum:"$price"}, avgQuantity:{$avg:"$quantity"} } }) 结果 xyz 10 15 abc 20 6 jkl 20 1
示例:按照 item 字段进行分组,统计每个 item 下面 quantity 的最大值与最小值
db.sales.aggregate({ $group: { _id: "$item", minQuantity: { $min: "$quantity" }, maxQuantity: { $max: "$quantity" } } }) 结果 xyz 10 20 abc 2 10 jkl 1 1
java代码
Aggregation aggregation = newAggregation( Aggregation.group("item").avg("quantity").as("avgQuantity").sum("price").as("priceCount") ); AggregationResults<BasicDBObject> sales = mongoTemplate.aggregate(aggregation, "sales", BasicDBObject.class); return sales.getMappedResults(); 查询结果 [ { "_id": "xyz", "avgQuantity": 15, "priceCount": 10 }, { "_id": "abc", "avgQuantity": 6, "priceCount": 20 }, { "_id": "jkl", "avgQuantity": 1, "priceCount": 20 } ]
示例:保留第一个内容与保留最后一个内容
db.sales.aggregate([ { $group : { _id : "$item", first: { $first : "$quantity"}, } } ]); 结果 xyz 10 abc 2 jkl 1