统计Mongo数组中相同对象的属性之和
统计Mongo数组中相同对象的属性之和
需求
需要统计app端用户的行为,按天分表,存入mongo。每次用户进行操作的时候,将数据存入app本地,下次用户启动的时候,提交存入mongo,删除app本地缓存。那么用户这个行为的文档就算是很复杂了。举个例子,存入mongo中文档为
/* 1 */
{
"_id" : ObjectId("5b8c996e5f814eb3c37eb49b"),
"userId" : 12323.0,
"appPlatform" : "ios",
"shortcutEntrance" : [
{
"entranceName" : "入口1",
"gmtCreate" : "2018-09-03 10:00:00"
},
{
"entranceName" : "入口2",
"gmtCreate" : "2018-09-03 10:00:00"
}
],
"classData" : [
{
"classId" : 123.0,
"position" : "left",
"gmtCreate" : "2018-09-03 10:00:00"
},
{
"classId" : 12356.0,
"position" : "right",
"gmtCreate" : "2018-09-03 10:00:00"
}
],
"channelVisit" : [
{
"channelType" : 2.0,
"gmtCreate" : "2018-09-03 10:00:00"
},
{
"channelType" : 3.0,
"gmtCreate" : "2018-09-03 10:00:00"
}
]
}
/* 2 */
{
"_id" : ObjectId("5b8e163df0fad825a708bc75"),
"userId" : 12323.0,
"appPlatform" : "ios",
"shortcutEntrance" : [
{
"entranceName" : "入口1",
"gmtCreate" : "2018-09-03 10:00:00"
},
{
"entranceName" : "入口2",
"gmtCreate" : "2018-09-03 10:00:00"
}
],
"classData" : [
{
"classId" : 123.0,
"position" : "left",
"gmtCreate" : "2018-09-03 10:00:00"
},
{
"classId" : 12356.0,
"position" : "right",
"gmtCreate" : "2018-09-03 10:00:00"
}
],
"channelVisit" : [
{
"channelType" : 2.0,
"gmtCreate" : "2018-09-03 10:00:00"
},
{
"channelType" : 3.0,
"gmtCreate" : "2018-09-03 10:00:00"
}
]
}
/* 3 */
{
"_id" : ObjectId("5b8e1642f0fad825a708bc76"),
"userId" : 12323.0,
"appPlatform" : "ios",
"shortcutEntrance" : [
{
"entranceName" : "入口1",
"gmtCreate" : "2018-09-03 10:00:00"
},
{
"entranceName" : "入口2",
"gmtCreate" : "2018-09-03 10:00:00"
}
],
"classData" : [
{
"classId" : 1234.0,
"position" : "left",
"gmtCreate" : "2018-09-03 10:00:00"
},
{
"classId" : 12356.0,
"position" : "right",
"gmtCreate" : "2018-09-03 10:00:00"
}
],
"channelVisit" : [
{
"channelType" : 2.0,
"gmtCreate" : "2018-09-03 10:00:00"
},
{
"channelType" : 3.0,
"gmtCreate" : "2018-09-03 10:00:00"
}
]
}
那么我需要统计classData.classId 相同的有多少。
解决方案
- 先对过滤出自己需要的数据
{"$project":{"classData.classId":1,"classData.position":1}}
获得得数据如下:
/* 1 */
{
"_id" : ObjectId("5b8c996e5f814eb3c37eb49b"),
"classData" : [
{
"classId" : 123.0,
"position" : "left"
},
{
"classId" : 12356.0,
"position" : "right"
}
]
}
/* 2 */
{
"_id" : ObjectId("5b8e163df0fad825a708bc75"),
"classData" : [
{
"classId" : 123.0,
"position" : "left"
},
{
"classId" : 12356.0,
"position" : "right"
}
]
}
/* 3 */
{
"_id" : ObjectId("5b8e1642f0fad825a708bc76"),
"classData" : [
{
"classId" : 1234.0,
"position" : "left"
},
{
"classId" : 12356.0,
"position" : "right"
}
]
}
_id 默认为1 也就是
{"$project":{"_id":1,"classData.classId":1,"classData.position":1}}
- 对classData数组进行分类切分
{"$unwind":"$classData"}
获取数据如下:
/* 1 */
{
"_id" : ObjectId("5b8c996e5f814eb3c37eb49b"),
"classData" : {
"classId" : 123.0,
"position" : "left"
}
}
/* 2 */
{
"_id" : ObjectId("5b8c996e5f814eb3c37eb49b"),
"classData" : {
"classId" : 12356.0,
"position" : "right"
}
}
/* 3 */
{
"_id" : ObjectId("5b8e163df0fad825a708bc75"),
"classData" : {
"classId" : 123.0,
"position" : "left"
}
}
/* 4 */
{
"_id" : ObjectId("5b8e163df0fad825a708bc75"),
"classData" : {
"classId" : 12356.0,
"position" : "right"
}
}
/* 5 */
{
"_id" : ObjectId("5b8e1642f0fad825a708bc76"),
"classData" : {
"classId" : 1234.0,
"position" : "left"
}
}
/* 6 */
{
"_id" : ObjectId("5b8e1642f0fad825a708bc76"),
"classData" : {
"classId" : 12356.0,
"position" : "right"
}
}
那么这样了就很好去获取classId得总数了
{"$group":{_id:"$classData.classId","classIdSum":{"$sum":1}}}
获取数据如下
/* 1 */
{
"_id" : 1234.0,
"classIdSum" : 1.0
}
/* 2 */
{
"_id" : 12356.0,
"classIdSum" : 3.0
}
/* 3 */
{
"_id" : 123.0,
"classIdSum" : 2.0
}
总命令如下:
db.getCollection('SHORTCUT_ENTRANCE_20180903').aggregate(
[
{"$project":{"classData.classId":1,"classData.position":1}},
{"$unwind":"$classData"},
{"$group":{_id:"$classData.classId","classIdSum":{"$sum":1}}}
])
数据统计存入业务表
结合Spring,使用mongoTemplate:
- 配置数据源
<!-- 数据源 -->
<mongo:db-factory id="mongoDbFactory" uri="mongodb://${mongo.database}:${mongo.password}@${mongo.host}:${mongo.port}/${mongo.username}?maxPoolSize=2000"/>
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
</bean>
- 从mongo获取统计数据存入业务表
核心代码如下:
Aggregation agg = Aggregation.newAggregation(
Aggregation.project("classData.classId","classData.position"),
Aggregation.unwind("$classData"),
Aggregation.group("$classData.classId").count().as("sim")
)
AggregationResults<BasicDBObject> objects = mongoTemplate.aggregate(agg,collection,BasicDBObject.class);//获取需要的统计数据
Iterator<BasicDBObject> iterator = objects.iterator();
while(iterator.hasNext()){
DBObject object = iterator.next();//获取统计数据中单个集合
........ //业务逻辑 存入业务表
}
统计Mongo数组中相同对象的属性之和的更多相关文章
- [原创]java WEB学习笔记59:Struts2学习之路---OGNL,值栈,读取对象栈中的对象的属性,读取 Context Map 里的对象的属性,调用字段和方法,数组,list,map
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- HTML中DOM对象的属性和方法的层级关系是怎样的?(目录即层次)
HTML中DOM对象的属性和方法的层级关系是怎样的?(目录即层次) 一.总结 一句话总结:目录就是测试题 1.document取得元素(get element)的方式有哪几种? 解答:四种,分别是id ...
- Java如何从数组中查找对象元素?
在Java中,如何从数组中查找对象元素? 示例 以下示例使用Contains方法来搜索数组中的String对象. package com.yiibai; import java.util.*; pub ...
- 统计numpy数组中每个值出现的个数
统计numpy数组中某一个值或某几个值出现的个数:sum(data==4) # 统计出现了几个cluster include0Cluster = sum(res == 0) include1Clust ...
- 将对象的所有属性名放到一个数组中 || 获得对象的所有属性名 || return;不具有原子性 || 怎样自己制作异常|| 判断对象有没有某个属性 || 当传递的参数比需要的参数少的时候,没有的值会被赋予undefined || 获得函数实际传递的参数 || 怎么用函数处理一个对象 || 用一个名字空间定义一个模块所有的函数 || 给一个对象添加方法
获得对象的所有属性名 || 将对象o的所有属性名放到数组中 var o = {x:1,y:2,z:3}; var arr = []; var i = 0; for(arr[i++] in o){};/ ...
- 你好,C++(38)从问题描述中发现对象的属性和行为 6.4 工资程序成长记:类与对象(上)
6.4 工资程序成长记:类与对象 “夜半三更哟,盼天明:寒冬腊月哟,盼春风.若要盼得哟,涨工资,岭上……”自从上次老板许诺给小陈涨工资以后,一转眼又过去几个月了,可是涨工资的事一点动静都没有.小陈只 ...
- iOS 查询数组中的对象
简述:Cocoa框架中的NSPredicate用于查询,原理和用法都类似于SQL中的where,作用相当于数据库的过滤取. 定义(最常用到的方法): NSPredicate *ca = [NSPred ...
- 全面理解Javascript中Function对象的属性和方法
http://www.cnblogs.com/liontone/p/3970420.html 函数是 JavaScript 中的基本数据类型,在函数这个对象上定义了一些属性和方法,下面我们逐一来介绍这 ...
- JS中访问对象的属性
方式一: 对象名.属性名; 方式二: 对象名["属性名"]; ★注意:方式二中,属性名以字符串的形式出现在方括号中,这意味着通过方式二访问属性的话,可以实现“动态访问对象的 ...
随机推荐
- 个推用户画像产品(个像)iOS集成实践
最近业务方给我们部门提了新的需求,希望能构建精准用户画像.我们尝试使用的是个推(之前专门做消息推送的公司)旗下新推出的产品“个像·用户画像”.根据官方的说法,个像能够为APP开发者提供丰富的用户画像数 ...
- k8s如何管理Pod(rc、rs、deployment)
是豆荚,可以把容器想像成豆荚里的豆子,把一个或多个关系紧密的豆子包在一起就是豆荚(一个Pod).在k8s中我们不会直接操作容器,而是把容器包装成Pod再进行管理(关于Pod,大家可以参考第十期的分享“ ...
- python---redis管道(事务)和发布订阅
管道:将数据操作放在内存中,只有成功后,才会一次性全部放入redis #管道(事务),要是都成功则成功,失败一个全部失败 #原理:将数据操作放在内存中,只有成功后,才会一次性全部放入redis pip ...
- [整理]WebAPI中应用oData
http://www.odata.org/ http://bitoftech.net/category/odata/ http://www.hanselman.com/blog/CreatingAnO ...
- 第13月第13天 iOS 放大消失动画
1. - (void) animate { [UIView animateWithDuration:0.9 animations:^{ CGAffineTransform transform = CG ...
- 第10月第13天 xcode ipa
1. xcodebuild -exportArchive -exportFormat ipa -archivePath RongChatRoomDemo\ 17-7-13\ 下午4.04.xcarch ...
- websocket知识简单总结!
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- 直接读取修改exe文件
1. 前言 配置器的编写有很多的方式,主要是直接修改原始的受控端的程序,有的方式是把受控端和配置信息都放到控制端程序的内部,在需要配置受控端的时候直接输入配置信息,生成受控端:也有的方式是在外部直接修 ...
- Convert Expression to Reverse Polish Notation
Given an expression string array, return the Reverse Polish notation of this expression. (remove the ...
- va_start(),va_end()函数应用【转】
转自:http://www.cnblogs.com/gogly/articles/2416833.html 原理解释: VA_LIST 是在C语言中解决变参问题的一组宏,在<stdarg.h&g ...