MongoDB 聚合Group(一)
一.简介
db.collection.group()使用JavaScript,它受到了一些性能上的限制。大多数情况下,$ group在Aggregation Pipeline提供了一种具有较少的限制适用的替代。可以通过指定的键的集合中的文档和执行简单的聚合函数。在2.2版本中,返回的数组可以包含最多20000个元素;即最多20000个独特的分组。
我们比较熟悉的group by 的sql语句select key from table groupby key,而mongoDB没提供SQL那样通过Group By就轻松实现数据库的分组功能,我们通过接口来实现的
db.collection.group({ key, reduce, initial[, keyf] [, cond] [, finalize] })
key |
作为分组的key |
reduce |
一个聚合函数操作文档的分组操作期间。这些函数可以返回一个sum或count。该函数接受两个参数:当前文档和这个群体聚集的结果文档。 |
initial |
初始化聚合结果文档变量,为空时自动为每列提供初始变量。 |
keyf |
可选。替代的key 字段。指定一个函数创建一个“key object”作为分组的key。使用keyf而是通过group by领域而不是现有的文档域键组。 |
cond |
过滤条件 |
finalize |
在db.collection.group()返回最终结果之前,此功能可以修改的结果文档或替换的结果文档作为一个整体。 |
二.Mongo VUE操作Group By
1.MonogoDB数据库中添加了订单的数据
/* 0 */ { "_id" : ObjectId("552a330e05c27486b9b9b650"), "_class" : "com.mongo.model.Orders", "onumber" : "002", "date" : ISODate("2014-01-03T16:03:00Z"), "cname" : "zcy", "item" : { "quantity" : 1, "price" : 4.0, "pnumber" : "p002" } } /* 1 */ { "_id" : ObjectId("552a331d05c275d8590a550d"), "_class" : "com.mongo.model.Orders", "onumber" : "003", "date" : ISODate("2014-01-04T16:03:00Z"), "cname" : "zcy", "item" : { "quantity" : 10, "price" : 2.0, "pnumber" : "p001" } } /* 2 */ { "_id" : ObjectId("552a333105c2f28194045a72"), "_class" : "com.mongo.model.Orders", "onumber" : "003", "date" : ISODate("2014-01-04T16:03:00Z"), "cname" : "zcy", "item" : { "quantity" : 30, "price" : 4.0, "pnumber" : "p002" } } /* 3 */ { "_id" : ObjectId("552a333f05c2b62c01cff50e"), "_class" : "com.mongo.model.Orders", "onumber" : "004", "date" : ISODate("2014-01-05T16:03:00Z"), "cname" : "zcy", "item" : { "quantity" : 5, "price" : 4.0, "pnumber" : "p002" } }
2.MongoDB实现分组并统计
1)我们要对日期和产品编码进行分组,并计算相同的产品的数量
Sql语句:Select date, pnumber,sum(quantity) as total from orders,items group by date, pnumber(少了两张表的关联的条件)
MongoDB:
db.orders.group({
key: { date:1,‘item.pnumber‘:1},
initial : {"total":0},
reduce : function Reduce(doc, out) {
out.total+=doc.item.quantity
} });
结果:
2)实现一天卖出了多少个产品,金额是多少,平均价格是多少
db.orders.group({
key: {date:1},
initial :{"total":0,"money":0},
reduce : function Reduce(doc, out) {
out.total+=doc.item.quantity;
out.money+=doc.item.quantity*doc.item.price;
},
finalize : function Finalize(out) {
out.avg=out.money/out.total
returnout;
}
});
结果:
3)keyf的使用
keyf 对日期进行处理并以作为key来进来分组
db.orders.group({
keyf: function (doc){
return{‘month‘:doc.date.getMonth()+1};
},
initial :{"total":0,"money":0},
reduce : function Reduce(doc, out) {
out.total+=doc.item.quantity;
out.money+=doc.item.quantity*doc.item.price;
},
finalize : function Finalize(out) {
out.avg=out.money/out.total
returnout;
}
});
结果:
三.Java MongoDB 实现
1)我们要对日期和产品编码进行分组,并计算相同的产品的数量
<strong> </strong> @Override public void getGroupCount(String collectionName) { BasicDBObject key = new BasicDBObject(); key.put("date", 1); key.put("item.pnumber", 1); //条件 BasicDBObject cond = new BasicDBObject(); //初始化 BasicDBObject initial = new BasicDBObject(); initial.append("total", 0); //reduce String reduce = "function Reduce(doc, out) { " + " out.total+=doc.item.quantity;" + "}"; SimpleDateFormat format=new SimpleDateFormat("yyyy-mm-dd"); BasicDBList groupList=(BasicDBList) mongoTemplate.getCollection(collectionName).group(key, cond, initial, reduce); if(groupList!=null&&groupList.size()>0){ System.out.println("date item.pnumber total"); for(int i=0;i<groupList.size();i++){ BasicDBObject obj=(BasicDBObject) groupList.get(i); System.out.println(format.format(obj.getDate("date"))+" "+obj.getString("item.pnumber")+" "+obj.getInt("total")); } } }结果:
2)实现一天卖出了多少个产品,金额是多少,平均价格是多少
@Override public void getGroupAvg(String collectionName) { BasicDBObject key = new BasicDBObject(); key.put("date", 1); //条件 BasicDBObject cond = new BasicDBObject(); //初始化 BasicDBObject initial = new BasicDBObject(); initial.append("total", 0); initial.append("money", 0.0); //reduce String reduce = "function Reduce(doc, out) { " + " out.total+=doc.item.quantity;" + " out.money+=doc.item.quantity*doc.item.price;" + "}"; String finalize="function Finalize (out) { " + " out.avg=out.money/out.total;" + " return out;" + "}"; SimpleDateFormat format=new SimpleDateFormat("yyyy-mm-dd"); BasicDBList groupList=(BasicDBList) mongoTemplate.getCollection(collectionName).group(key, cond, initial, reduce, finalize); if(groupList!=null&&groupList.size()>0){ System.out.println("date total money avg"); for(int i=0;i<groupList.size();i++){ BasicDBObject obj=(BasicDBObject) groupList.get(i); System.out.println(format.format(obj.getDate("date"))+" "+obj.getInt("total")+" "+obj.getInt("money")+" "+obj.getDouble("avg")); } } }结果:
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。