一、BasicDBObject
整个聚合查询是统计用户的各种状态下的用户数量为场景:
1.筛选条件:
date为查询日期:
| 
 
								1
 
								2
 
								3
						  | 
BasicDBObject Query = new BasicDBObject(); 
Query.put("time",new BasicDBObject("$gte", date + " 00:00:00")
.append("$lte", date + " 23:59:59"));
 | 
如果有多个条件:直接加Query.put("status", 0);
如果有OR筛选:
| 
 
								1
 
								2
 
								3
 
								4
						  | 
BasicDBList values = new BasicDBList();
values.add(new BasicDBObject("status", new BasicDBObject("$exists",false)));
values.add(new BasicDBObject("status", 0));
Query.put("$or", values);
 | 
其中 new BasicDBObject("$exists",false)) 就是“status”不存在(mongodb文档可不等于实体的字段)
2.拼接match
| 
 
								1
						  | 
DBObject Match = new BasicDBObject("$match", Query);
 | 
将上一步的Query放入macth筛选中
3.拼接分组条件
此步相当于SQL的Group By
| 
 
								1
 
								2
						  | 
BasicDBObject GroupBy = new BasicDBObject();// 分组条件
GroupBy.put("userId", "$userId");//根据用户ID来分组
 | 
同第一步的筛选一样,如果有多个分组可直接添加在后面:GroupBy.put("status", "$status");
4.分组后查询
首先把分组拼接上:
| 
 
								1
						  | 
DBObject Select = new BasicDBObject("_id", GroupBy);
 | 
如果我们要对分组后的数据进行操作:(这里是用户的统计数量)
| 
 
								1
						  | 
Select.put("count", new BasicDBObject("$sum", 1));
 | 
5.拼接$group
| 
 
								1
						  | 
DBObject Group = new BasicDBObject("$group", Select);
 | 
至此。我们拼接,mongodb的语句到此结束
下面我们开始查询操作:
| 
 
								1
 
								2
 
								3
 
								4
						  | 
import com.mongodb.AggregationOutput;
import org.springframework.data.mongodb.core.MongoTemplate;
AggregationOutput Output = mongoTemplate.getCollection("这里是mongodb的数据表名")
.aggregate(Match, Group);
 | 
读取查询结果:
| 
 
								1
 
								2
 
								3
 
								4
 
								5
 
								6
 
								7
 
								8
 
								9
 
								10
 
								11
 
								12
 
								13
						  | 
Iterable<DBObject> map = Output.results();
//遍历map
for (DBObject dbObject : map) {
//这里读取到的map为{"_id":{"userId":1,"status"0}}... 
Map<String, Object> resultMap = (Map<String, Object>) dbObject.get("_id");
//这里截取掉.0 
Integer userId = Integer.parseInt(CommUtil.toString(ausgMap.get("userId")).replace(".0",""));
//在这里我们就可以对我们的数据进行操作了; 
Integer count = Integer.parseInt(CommUtil.toString(dbObject.get("count")));
}
 | 
二、DBObject
不多说,如果大家觉得第一种方法特别长篇大论,那么下面我给大家带来一种代码更简洁的聚合查询:
直接上代码吧。
1.注意导入的包:
| 
 
								1
						  | 
import com.mongodb.DBObject; import com.mongodb.util.JSON;
 | 
2.$macth:
(beginDay-查询开始日期;endDay-查询结束日期)
| 
 
								1
 
								2
						  | 
DBObject match = (DBObject) JSON.parse("{$match:{'status':'1','time':
{$gte:'"+beginDay+"',$lte:'"+endDay+"'}}}");
 | 
3.$group:
(以userId分组,统计用户数量,累加amout字段值,取amout字段最大值)
| 
 
								1
 
								2
						  | 
DBObject group = (DBObject) JSON.parse("{$group:{_id:'$userId', 
count:{$sum:1},total:{$sum:'$amount'},maxSigle:{$max:'$amount'}}}");
 | 
条件拼接完,开始查询:
| 
 
								1
 
								2
 
								3
						  | 
List<DBObject> list = new ArrayList<DBObject>();
list.add(match); list.add(group);
AggregationOutput Output = mongoTemplate.getCollection("表名").aggregate(list);
 | 
遍历结果就不用在说了。上面已经详细描述了
第二种方法是不是比一种方式简单多了。但是比较考验自身对mongodb语句熟悉性。
【扩展】
接着上面的方法进行扩展
| 
 
								1
 
								2
 
								3
 
								4
 
								5
 
								6
 
								7
 
								8
 
								9
 
								10
 
								11
 
								12
 
								13
 
								14
 
								15
 
								16
 
								17
 
								18
 
								19
 
								20
 
								21
 
								22
 
								23
 
								24
 
								25
						  | 
//status 为0或者为1 ; type 不为11;time在beginDay ~ endDay时间段内
DBObject match = (DBObject) JSON.parse("{$match:{'status':{$in:['0','1']},
type:{$ne:11},'time':{$gte:'"+beginDay+"',$lte:'"+endDay+"'}}}");
//以用户Id分组,统计查询次数,取最后一次time的时间
DBObject group = (DBObject) JSON.parse("{$group:{_id:'$userId', 
count:{$sum:1},lastTime:{$max:'$time'} }}");
//在上一步统计出的结果中筛选次数大于100的数据
DBObject groupMatch = (DBObject) JSON.parse("{$match:{count:{$gte:100}}}");
//$project----查询结果中需要显示哪些字段,显示则设置为1。如下需要不显示_id 域(字段),则需如下指定:
//db.集合名.aggregate( [ { $project : { _id: 0, count: 1 , lastSuccTime: 1 } } ] )
DBObject project = (DBObject) JSON.parse("{$project:{_id:1,count:1,lastSuccTime:1}}");
DBObject sort = (DBObject) JSON.parse("{$sort:{'count':-1}}");//排序
List<DBObject> list = new ArrayList<DBObject>();
list.add(match);
list.add(group);
list.add(groupMatch);
list.add(project);
list.add(sort);
AggregationOutput catchOutPut = mongoTemplate.getCollection("表名")
.aggregate(list);//查询结果
 | 
三、BasicDBObject+脚本语句
| 
 
								1
 
								2
 
								3
 
								4
 
								5
 
								6
 
								7
 
								8
 
								9
 
								10
						  | 
BasicDBObject groupIndex = new BasicDBObject();
BasicDBObject distinctQuery = new BasicDBObject();
distinctQuery.put("userId", new BasicDBObject("$in", userIds));//UserIds数组
BasicDBObject initIndex = new BasicDBObject();
initIndex.put("count", 0);//给count赋初值
// 脚本(doc代表数据库的数据.prev代表查询结果//prev.count这里的count就是上一步initIndex的count)
String reduce = "function(doc, prev) {if(doc.status==0){prev.count+= 1;};}";
List<Map<String, Object>> basicDBList = (List<Map<String, Object>>) mongoTemplate.
getCollection("Collection").group(groupIndex, distinctQuery, initIndex, reduce, null);
 | 
最后循环遍历List即可得到结果【PS:group这种聚合方式有个限制条件—>超过20000数据就会报错】
以上就是我在普通业务处理中用到mongodb聚合处理。如果有更好的方法或是有需要改进的地方,欢迎大家给我留言~
原文链接:https://juejin.im/post/5ab8a2306fb9a028d9372666
相关文章
- 64M VPS建站:能否支持高流量网站运行? 2025-06-10
 - 64M VPS建站:怎样选择合适的域名和SSL证书? 2025-06-10
 - 64M VPS建站:怎样优化以提高网站加载速度? 2025-06-10
 - 64M VPS建站:是否适合初学者操作和管理? 2025-06-10
 - ASP.NET自助建站系统中的用户注册和登录功能定制方法 2025-06-10
 
- 2025-07-10 怎样使用阿里云的安全工具进行服务器漏洞扫描和修复?
 - 2025-07-10 怎样使用命令行工具优化Linux云服务器的Ping性能?
 - 2025-07-10 怎样使用Xshell连接华为云服务器,实现高效远程管理?
 - 2025-07-10 怎样利用云服务器D盘搭建稳定、高效的网站托管环境?
 - 2025-07-10 怎样使用阿里云的安全组功能来增强服务器防火墙的安全性?
 
快网idc优惠网
QQ交流群
- 
            2025-05-29 95
 - 
            2025-05-26 104
 - 
            2025-05-29 101
 - 
            2025-05-29 26
 - 
            2025-05-25 16
 
        
    		
            	
        
        
        