MongoDB的聚合功能使用
来源:互联网 发布:mac os 哪个版本号 编辑:程序博客网 时间:2024/06/06 01:57
MongoDB的聚合功能的使用
我在项目中主要使用的数据库是MongoDB,版本为2.4.6,目前最新的版本为3.0(还没有使用用,据说增加了很多新功能及改进)。
很久以前完成了一个报表开发任务,用到了聚合,这里就简单的做了个记录,也分享给其他人。projectmonthdata表(习惯称集合为表)中保存了每个月份的项目冻结数据,我选选取了某条记录的部分字段值:
{
"_id" : ObjectId("5339cfe7e0cca65106fa33e7"),
"year" : 2014,
"month" : 3,
"_id" : ObjectId("5339cfe7e0cca65106fa33e7"),
"year" : 2014,
"month" : 3,
"date":1396281599999,
"date" : NumberLong("1396281599999"),
"project_id" : ObjectId("53391501e0cca65106f957d3"),
"org_id":ObjectId(525ded94ede0a8ee8c1ca6dd),
"month_investment_allocated" : 135.0,
"month_investment_designated" : 11.0,
"month_investment" : 146.0,
"month_sales_cost" : 50.0,
"month_sales_revenue" : 100.0,
"month_sales_profit" : 50.0
}
"date" : NumberLong("1396281599999"),
"project_id" : ObjectId("53391501e0cca65106f957d3"),
"org_id":ObjectId(525ded94ede0a8ee8c1ca6dd),
"month_investment_allocated" : 135.0,
"month_investment_designated" : 11.0,
"month_investment" : 146.0,
"month_sales_cost" : 50.0,
"month_sales_revenue" : 100.0,
"month_sales_profit" : 50.0
}
其中project_id对应了project表里面的_id,org_id对应了organization表里面的_id,month_investment_allocated是项目的部门投入费用,month_investment_designated是项目的研发投入费用,month_investment是项目的总费用,month_sales_cost是销售支出费用,month_sales_revenue是销售收益,month_sales_profit是销售利润,year是哪一年,month是哪个月,date是时间转换成的long格式。
需求如下:界面上查询报表是可以选择某几个月的,需要将同一个项目不同月份的6中费用累加求和,聚合为一条数据。其中month_investment_allocated,month_investment_designated,month_investment相加小于0则这条记录不参与聚合(这里需求我都简化了,实际开发比这个复杂,因为主要只看聚合部分)。
mongodb的collection有个方法是aggregate如下:aggregate(query,group),第一个参数query是查询的限制条件,也就是查询符合哪些条件的数据,后面的参数group是可以有多个的,作为聚合分组。实际代码如下;
//这是第一个参数,也就是条件
DBObject match = new BasicDBObject().append(
"$match",
new BasicDBObject()
.append("$or", queryCostOrSales)
.append("date",
new BasicDBObject().append("$gt",
startDate.getTime()).append(
"$lte", endDate.getTime()))
.append(Project.F_FUNCTION_ORGANIZATION,
new BasicDBObject().append("$in",
orgIds)));
"$match",
new BasicDBObject()
.append("$or", queryCostOrSales)
.append("date",
new BasicDBObject().append("$gt",
startDate.getTime()).append(
"$lte", endDate.getTime()))
.append(Project.F_FUNCTION_ORGANIZATION,
new BasicDBObject().append("$in",
orgIds)));
这里用json表示出来是这样的:{"$match":{{"$or“:[month_investment_allocated:{"$gt",0},
month_investment_designated:{"$gt",0},
month_investment:{"$gt",0}]},
{date:{"$gt":输入的开始时间,"$lte":"输入的结束时间"}},{org_id:{"$in":[输入的组织id数组]}}}}
表示的意思为:match去匹配month_investment_allocated、month_investment_designated、month_investment这三个值,值要大于0,紧接着要筛选出表中date字段的值要大于给定的输入时间,小于等于给定的结束时间,后面还有一个限制条件表中的org_id字段的值是给定的org_id的数组。
//这是第二个参数,也就是分组,多个的我还没用过
DBObject group = new BasicDBObject()
.append("$group",
new BasicDBObject()
.append("_id",
"$"
+ ProjectMonthData.F_PROJECTID)
.append(IProjectETL.F_INVESTMENT_ALLOCATED,
new BasicDBObject()
.append("$sum",
"$month_investment_allocated"))
.append(IProjectETL.F_INVESTMENT_DESIGNATED,
new BasicDBObject()
.append("$sum",
"$month_investment_designated"))
.append(IProjectETL.F_INVESTMENT,
new BasicDBObject().append(
"$sum",
"$month_investment"))
.append(IProjectETL.F_SALES_COST,
new BasicDBObject().append(
"$sum",
"$month_sales_cost"))
.append(IProjectETL.F_SALES_REVENUE,
new BasicDBObject().append(
"$sum",
"$month_sales_revenue"))
.append("sales_profit",
new BasicDBObject().append(
"$sum",
"$month_sales_profit")));
DBObject group = new BasicDBObject()
.append("$group",
new BasicDBObject()
.append("_id",
"$"
+ ProjectMonthData.F_PROJECTID)
.append(IProjectETL.F_INVESTMENT_ALLOCATED,
new BasicDBObject()
.append("$sum",
"$month_investment_allocated"))
.append(IProjectETL.F_INVESTMENT_DESIGNATED,
new BasicDBObject()
.append("$sum",
"$month_investment_designated"))
.append(IProjectETL.F_INVESTMENT,
new BasicDBObject().append(
"$sum",
"$month_investment"))
.append(IProjectETL.F_SALES_COST,
new BasicDBObject().append(
"$sum",
"$month_sales_cost"))
.append(IProjectETL.F_SALES_REVENUE,
new BasicDBObject().append(
"$sum",
"$month_sales_revenue"))
.append("sales_profit",
new BasicDBObject().append(
"$sum",
"$month_sales_profit")));
这里我就不写json格式的了。
然后把这两个参数传入到目标方法aggregate中,AggregationOutput aggregate = prjmd.aggregate(match, group);
Iterator<DBObject> iter = aggregate.results().iterator();
Iterator<DBObject> iter = aggregate.results().iterator();
这个itera中的DBObject类型的数据就是聚合出来的每一条新数据,然后遍历取出里面费用和_id,重新组合成新对象,就可以了。
详细的下次会解释。
1 0
- MongoDB的聚合功能使用
- mongodb的聚合使用
- MongoCola使用教程 1 - MongoDB的基本操作和聚合功能
- MongoDB aggregate聚合函数的使用
- MongoDB中聚合(aggregate)的使用
- 使用百度地图的点聚合功能
- MongoDB的聚合查询
- MongoDB的聚合框架
- MongoDB的聚合操作
- MongoDB的聚合(aggregate)
- 非常使用的mongodb的聚合函数(使用SpringDataMongoDb)
- 使用MongoDB $lookup聚合器
- Java中使用mongodb的aggregate聚合查询
- MongoDB的聚合函数 Aggregate
- MongoDB的聚合函数 Aggregate
- MongoDB Aggregation, mongoDB的聚合操作
- MongoDB:6-MongoDB的聚合和管道
- 使用mongodb 的MapReduce功能笔记
- matlab conv2、filter2、imfilter的区别
- 建立多人协作git仓库/git 仓库权限控制(SSH)
- Android生成签名包以及空白包打签名包
- mac机下切换不同版本的jdk
- java 时间转换
- MongoDB的聚合功能使用
- Redis中PipeLine使用(二)---批量get与批量set
- Java 理论与实践: 非阻塞算法简介--转载
- 常用的机器学习&数据挖掘翻译(转)
- Codevs_P2981 查字典1(BIT)
- 设置video.js多视频连续播放
- yycg之用户身份校验(二)
- Elasticsearch-PHP 索引操作
- 鸟哥的Linux私房菜(基础篇)- 一个简单的 SPFdisk 分割实例