统计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中访问对象的属性
方式一: 对象名.属性名; 方式二: 对象名["属性名"]; ★注意:方式二中,属性名以字符串的形式出现在方括号中,这意味着通过方式二访问属性的话,可以实现“动态访问对象的 ...
随机推荐
- AngularJS学习笔记3——AngularJS的工作原理
个人觉得,要很好的理解AngularJS的运行机制,才能尽可能避免掉到坑里面去.在这篇文章中,我将根据网上的资料和自己的理解对AngularJS的在启动后,每一步都做了些什么,做一个比较清楚详细的解析 ...
- 个推基于Consul的配置管理
作者:个推应用平台基础架构高级研发工程师 阿飞 在微服务架构体系中,由于微服务众多,服务之间又有互相调用关系,因此,一个通用的分布式配置管理是必不可少的.一般来说,配置管理需要解决配置集中管理.在系统 ...
- Linux系统下/tmp目录文件重启后自动删除,不重启自动删除10天前的/TMP的文件(转)
/tmp目录文件重启后自动删除现在知道有ubuntu和solaris系统source:http://blog.chinaunix.net/uid-26212859-id-3567875.html经常会 ...
- 异步消息处理机制Handler
Android 中的异步消息处理主要由四个部分组成,Message.Handler.MessageQueue 和Looper. 1. Message Message 是在线程之间传递的消息,它可以在内 ...
- Spark记录-SparkSQL
Spark SQL的一个用途是执行SQL查询.Spark SQL也可以用来从现有的Hive安装中读取数据.有关如何配置此功能的更多信息,请参阅Hive表部分.从另一种编程语言中运行SQL时,结果将作为 ...
- Spring Cloud(十四)Config 配置中心与客户端的使用与详细
前言 在上一篇 文章 中我们直接用了本应在本文中配置的Config Server,对Config也有了一个基本的认识,即 Spring Cloud Config 是一种用来动态获取Git.SVN.本地 ...
- [原]Android 初遇Http错误 httpClient.execute
错误源头: HttpResponse response = httpClient.execute(httpget); 错误信息: android.os.NetworkOnMainThreadExcep ...
- Apache的对象复制详解
BeanUtils.copyProperties 和 PropertyUtils.copyProperties 两个工具类都是对两个bean之前存在name相同的属性进行处理,无论是源bean或者目标 ...
- CF11D A Simple Task(状压DP)
\(solution:\) 思路大家应该都懂: 状压DP:\(f[i][j]\),其中 \(i\) 这一维是需要状压的,用来记录19个节点每一个是否已经走过(走过为 \(1\) ,没走为 \(0\) ...
- thinkphp5学习总结!
数据库操作之原生sql操作 <?php namespace app\index\controller; use think\Db; class Index { public function i ...