mongodb常用分组统计-分组分页求最近时间
2016-04-30 17:14
579 查看
工作两年了,从来没写过博客,现在想想是时候写写平时工作中遇到的问题了。脑子不好使,还是笔头好啊。
废话不多说,现在工作要求使用mongodb-初识mongodb还得从简单的命令开始,增删改查。现在要实现一个分组统计的功能,背景如下:
活动分布者1---->n活动---->n活动报名用户【同一个活动一个人报名一次openid区分】
现在想在页面展现【当前发布者】【根据openid分组】【然后取每组最近时间的】【报名用户的相信信息】
分析可知:先要有一个条件查询,一个group,一次排序,取最近时间,还要有详细信息,然后还必须支持分页!
查了很多竟然没有搜到我这个需求的,我觉得这个需求经常用到才是,没办法自己拿着mongodb权威指南啃,发现了mapreduce可以实现,具体实现如下:
但是上面方式有个缺点是无法分页,我试了很多也没有发现他支持分页?无法分页不符合需求,遂继续寻找解决方案
利用mongodb的管道技术查询,刚开始的时候其实就考虑使用管道,无奈当进行到group时不知道怎样进行,因为一旦根据某个字段group以后,得到的结果集里只有该字段的信息,而我需要的是分组后每组最近时间的那一条记录信息【页面需要展示什么字段就得查询出来哪些字段】仔细看书终于找到解决方案:
废话不多说,现在工作要求使用mongodb-初识mongodb还得从简单的命令开始,增删改查。现在要实现一个分组统计的功能,背景如下:
活动分布者1---->n活动---->n活动报名用户【同一个活动一个人报名一次openid区分】
现在想在页面展现【当前发布者】【根据openid分组】【然后取每组最近时间的】【报名用户的相信信息】
分析可知:先要有一个条件查询,一个group,一次排序,取最近时间,还要有详细信息,然后还必须支持分页!
查了很多竟然没有搜到我这个需求的,我觉得这个需求经常用到才是,没办法自己拿着mongodb权威指南啃,发现了mapreduce可以实现,具体实现如下:
db.applyuser.runCommand({ 'group':{ 'ns':'applyuser'--指定要分组的集合名称 'key':{'openid':true},--文档分组的依据 'initial':{'applyTime':0},--初始化数据,applyTime每组初始为0 '$reduce':function(doc,prev){--reduce,分组后,每组内数据执行,取最新时间 if(doc.applyTime > prev.applyTime){ prev._id = doc._id; prev.headimgurl = doc.headimgurl; prev.name = doc.name; prev.phone = doc.phone; prev.applyCount = doc.applyCount; }}, 'condition':{'staffID':'214be1c2bcba486faaa4c329afcf479b','$where':'function(){return this.applyCount < 5}'},--条件查询,可嵌套where查询 } })
但是上面方式有个缺点是无法分页,我试了很多也没有发现他支持分页?无法分页不符合需求,遂继续寻找解决方案
利用mongodb的管道技术查询,刚开始的时候其实就考虑使用管道,无奈当进行到group时不知道怎样进行,因为一旦根据某个字段group以后,得到的结果集里只有该字段的信息,而我需要的是分组后每组最近时间的那一条记录信息【页面需要展示什么字段就得查询出来哪些字段】仔细看书终于找到解决方案:
db.applyuser.aggregate( { "$sort":{"applyTime":1}--按时间排序 },{ "$group":{"_id":"$openid","id1":{"$first":"$_id"},"name":{"$first":"$name"}}--按openid分组,取每组内的first的name赋给name },{ "$limit":5--结果集返回五条数据 },{ "$skip":1--跳过第一条数据,从第二条数据开始 } )以下为对应的spring-mongotemplate查询方法
TypedAggregation<ApplyUser> agg = Aggregation.newAggregation( ApplyUser.class , Aggregation.match(c) , Aggregation.sort(new Sort(Sort.Direction.DESC, "applyTime")) , Aggregation.group("openid") .first("id").as("aliasID") .first("email").as("email") .first("country").as("country") .first("province").as("province") .first("city").as("city") .first("name").as("name") .first("sex").as("sex") .first("actTitle").as("actTitle") .first("applyCount").as("applyCount") .first("phone").as("phone") .first("openid").as("openid") .first("headimgurl").as("headimgurl") , Aggregation.skip(page.getFirstResult()) , Aggregation.limit(page.getPageSize()) ); AggregationResults aggResults = mongoTemplate.aggregate(agg, SystemContent.COLLECTION_NAME_APPLYUSER, ApplyUser.class);有个问题就是执行下面后结果集中的_id的值是分组字段的值,封装到对象中没有获得到真实的id,但是页面展现的操作还都需要这唯一ID,我暂时是新建了个aliasID用来存储,不知道各位有别的方式吗?
Aggregation.group("openid")
相关文章推荐
- Linux下安装MongoDB3.2.5
- MongoDB入门教程(二)
- MONGODB的内部构造 FROM 《MONGODB THE DEFINITIVE GUIDE》
- MONGODB的内部构造 FROM 《MONGODB THE DEFINITIVE GUIDE》
- 浅尝key-value数据库(三)——MongoDB的分布式
- 浅尝key-value数据库(二)——MongoDB的优与劣
- 浅尝key-value数据库(三)——MongoDB的分布式
- 浅尝key-value数据库(二)——MongoDB的优与劣
- 可配置多级指标投票打分应用设计(1)
- MongoDB-基本命令学习一
- Bluemix的三台虚拟机做MongoDB Replica Set
- MongoDB 针对嵌套对象,多层级结构存储,增删改查
- MongoDB -- MongoClient连接池用法
- MongoDB学习笔记-查询
- MongoDB分片集群还原
- MongoDB入门教程(一)
- Mongodb 创建索引
- nagios监控mongodb
- Node.js和MongoDB——从MongoJS开始
- mogoTemplate 模板 实现mongodb java的操作 ,根据经纬度查询周边