MongoDB 聚合Group(一)
原文:http://blog.csdn.net/congcong68/article/details/45012717
一.简介
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"));
- }
- }
- }
结果:
MongoDB 聚合Group(一)的更多相关文章
- mongodb MongoDB 聚合 group
MongoDB 聚合 MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果.有点类似sql语句中的 count(*). 基本语法为:db.col ...
- mongodb MongoDB 聚合 group(转)
MongoDB 聚合 MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果.有点类似sql语句中的 count(*). 基本语法为:db.col ...
- mongodb聚合 group
MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果.有点类似sql语句中的 count(*). 基本语法为:db.collection.agg ...
- MongoDB 聚合管道(Aggregation Pipeline)
管道概念 POSIX多线程的使用方式中, 有一种很重要的方式-----流水线(亦称为"管道")方式,"数据元素"流串行地被一组线程按顺序执行.它的使用架构可参考 ...
- Mongodb学习笔记四(Mongodb聚合函数)
第四章 Mongodb聚合函数 插入 测试数据 ;j<;j++){ for(var i=1;i<3;i++){ var person={ Name:"jack"+i, ...
- 浅析mongodb中group分组
这篇文章主要介绍了浅析mongodb中group分组的实现方法及示例,非常的简单实用,有需要的小伙伴可以参考下. group做的聚合有些复杂.先选定分组所依据的键,此后MongoDB就会将集合依据选定 ...
- MongoDB 聚合
聚合操作过程中的数据记录和计算结果返回.聚合操作分组值从多个文档,并可以执行各种操作,分组数据返回单个结果.在SQL COUNT(*)和group by 相当于MongoDB的聚集. aggregat ...
- MongoDB聚合
--------------------MongoDB聚合-------------------- 1.aggregate(): 1.概念: 1.简介 ...
- MongoDB 聚合分组取第一条记录的案例及实现
关键字:MongoDB: aggregate:forEach 今天开发同学向我们提了一个紧急的需求,从集合mt_resources_access_log中,根据字段refererDomain分组,取分 ...
随机推荐
- 解决使用vim-go插件时候保存go代码导致设置好的折叠消失的问题
我之前在用vim编辑python代码的时候,折叠的功能都没啥问题 后来在编辑go代码的时候,我发现我一保存,折叠全都消失了,我很费解,就推断跟我使用的插件有关系,因为我保存的时候会触发gofmt插件格 ...
- jsp页面中引入java类
<%@ page import="java.util.*" %>
- Android通过onDraw实现在View中绘图操作
Android绘图操作,通过继承View实现,在onDraw函数中实现绘图. 下面是一个简单的例子: public class AndroidTest extends Activity { /** C ...
- v-if与v-show区别
在v-show中,元素是一直存在的,当v-show为false时,元素display:none只是隐藏了而已. v-if 作用:判断是否加载固定的内容,如果为真,则加载:为假时,则不加载. 用处:用在 ...
- CentOS Linux上搭建PPPoE服务器及拨号设置
CentOS Linux上搭建PPPoE服务器及拨号设置 搭建PPPoE,成功了的话,就觉得超级简单,在CentOS Linux更是5步左右就能搞定. 1.安装pppoe,安装完成后,会有pppoe- ...
- [CF954G]Castle Defense
题目大意:有$n$个点,每个点最开始有$a_i$个弓箭手,在第$i$个位置的弓箭手可以给$[i-r,i+r]$区间加上$1$的防御,你还有$k$个弓箭手,要求你最大化最小防御值 题解:二分答案,从右向 ...
- BZOJ3876 [Ahoi2014&Jsoi2014]支线剧情 【有上下界费用流】
题目 [故事背景] 宅男JYY非常喜欢玩RPG游戏,比如仙剑,轩辕剑等等.不过JYY喜欢的并不是战斗场景,而是类似电视剧一般的充满恩怨情仇的剧情.这些游戏往往 都有很多的支线剧情,现在JYY想花费最少 ...
- 配置postfix支持虚拟域和虚拟用户
请先看基础篇 https://www.cnblogs.com/hellojackyleon/p/9281620.html https://sourceforge.net/projects/couri ...
- 口红游戏 插口红游戏 h5页面开发
目前火热的口红机游戏,需要在设备前参与,然后成功后即可赢得口红,作为平台运营者来说还是比较重资产的,目前我们将它搬到了线上.每个人都可以远程玩这样的口红机游戏了.直接在手机微信里试玩,成功后,后台即可 ...
- d3.js path路径
转自:http://www.d3js.cn/?p=68 svg的path标签被称为”可以组成任何形状的形状” SVG Path可以绘制任何形状的图形,包括矩形,圆形,椭圆,折线,多边形,直线,曲线等. ...