统计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中访问对象的属性
方式一: 对象名.属性名; 方式二: 对象名["属性名"]; ★注意:方式二中,属性名以字符串的形式出现在方括号中,这意味着通过方式二访问属性的话,可以实现“动态访问对象的 ...
随机推荐
- Linux常用命令history/tcpdump/awk/grep
1. 历史命令回显history 查询是什么时间什么人操作过文件: echo 'export HISTTIMEFORMAT="%F %T `whoami` "' >> ...
- sublime Text不能安装插件的解决办法
我的sublime Text不能安装插件,提示如下错误 解决办法如下: 1.点击Preferences > Browse Packages菜单 2.进入打开的目录的“上层目录”,然后再进入Ins ...
- OpenStack API部分高可用配置(二)
一.安装与配置HAProxy 1.调整内核参数,允许绑定VIP: vim /etc/sysctl.conf [内容] net.ipv4.ip_nonlocal_bind=1 sysctl -p 2.安 ...
- SQL记录-PLSQL函数
PL/SQL函数 PL/SQL函数与过程相同,不同之处在于函数有一个返回值.因此,前面的章节中的所有讨论都适用于函数. 创建函数 建立一个独立函数可以使用CREATE FUNCTION语句创建.CRE ...
- 第一次使用 markdown 写博客
Web前端 js 框架(四选一) 有可能的话,学 Vue.js ,React.js ,Angular.js,Awrelia css 学习 Sass 学会 css 的可编程 HTML5 详细语法 Nod ...
- GraphChi/graphchi-java程序配置
1.导入graphchi-java maven项目时报错: Plugin execution not covered by lifecycle configuration: org.scala-too ...
- html5 canvas高级贝塞尔曲线运动动画(好吧这一篇被批的体无完肤!都说看不懂了!没办法加注释了!当然数学不好的我也没办法了,当然这还涉及到一门叫做计算机图形学的学科)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- java Runnable、Callable、FutureTask 和线程池
一:Runnable.Callable.FutureTask简介 (1)Runnable:其中的run()方法没有返回值. ①.Runnable对象可以直接扔给Thread创建线程实例,并且创建的线程 ...
- 第10月第1天 storyboard uitableviewcell
1. 如图,我们在Cell的属性界面对其进行了注册,identifier 为"TableViewCell" 不需要在 ViewDidLoad 对其进行注册了,如果进行注册的话,则对 ...
- 【配置】Spring Struts配置信息