irpas技术客

SpringBoot+mongodb实现分组统计、时间范围查询、去重排序查询、组合排序、分页查询_12程序猿_aggregate 去重

网络 5888

SpringBoot+mongodb实现分组统计、时间范围查询、去重排序查询、组合排序

目录 一、分组统计(Aggregation)1.按某字段分组统计2.多字段分组统计 二、时间范围查询三、去重排序查询四、组合排序五、分页查询

一、分组统计(Aggregation) 1.按某字段分组统计 /** * 根据分类名称 分组统计销售数量 * @param dataType 1:本日 2:本月 3:本年 * @return */ @RequestMapping("/findInfoByGroup") public List<Map> findInfoByGroup(){ //从mongodb里获取满足条件的记录 status:状态 1:上架 2:下架 Criteria criteria = Criteria.where("status").is(1); //聚合函数查询统计信息 Aggregation aggregation = Aggregation.newAggregation(Aggregation.match(criteria), //按分类名称 统计 销售数量 Aggregation.group("category").sum("sale_num").as("total"), //按照total降序 Aggregation.sort(Sort.Direction.DESC,"total") ); AggregationResults<Map> aggregationResults = mongoTemplate.aggregate(aggregation,Product.class,Map.class); List<Map> list = aggregationResults.getMappedResults(); return list; }

category:要分组的字段 sale_num:要统计的字段 total:别名

返回结果:

[ { "_id": "口红", "total": 2224.0 }, { "_id": "面膜", "total": 997.0 }, { "_id": "文具", "total": 799.0 }, { "_id": "男装", "total": 675.0 }, { "_id": "女装", "total": 448.0 } ]

_id本来应该是对应查询的字段,没有处理,spring会将分组字段自动转换为_id

2.多字段分组统计 /** * 根据分类名称和规格 分组统计销售数量 * @param * @return */ @RequestMapping("/findInfoByGroup1") public List<Map> findInfoByGroup1(){ //从mongodb里获取最新的一条记录 status:状态 1:上架 2:下架 Criteria criteria = Criteria.where("status").is(1); //聚合函数查询统计信息 Aggregation aggregation = Aggregation.newAggregation(Aggregation.match(criteria), //按分类名称 统计 销售数量 Aggregation.group("category","specification").sum("sale_num").as("total"), //按照total降序 Aggregation.sort(Sort.Direction.DESC,"total") ); AggregationResults<Map> aggregationResults = mongoTemplate.aggregate(aggregation,Product.class,Map.class); List<Map> list = aggregationResults.getMappedResults(); return list; }

返回结果:

[ { "_id": { "category": "口红", "specification": "个" }, "total": 2224.0 }, { "_id": { "category": "面膜", "specification": "盒" }, "total": 997.0 }, { "_id": { "category": "文具", "specification": "套" }, "total": 799.0 }, { "_id": { "category": "男装", "specification": "件" }, "total": 675.0 }, { "_id": { "category": "女装", "specification": "件" }, "total": 448.0 } ] 二、时间范围查询

方式一:

/** * 同一个字段 按范围查询 * @return */ @RequestMapping("/findInfoByTime") public List<Product> findInfoByTime(@RequestBody Product product){ Criteria criteria = new Criteria(); //创建时间 开始时间 结束时间 if(!ObjectUtils.isEmpty(product.getStartTime()) || !ObjectUtils.isEmpty(product.getEndTime())){ criteria = criteria.and("create_time"); if(!ObjectUtils.isEmpty(product.getStartTime())){ criteria.gte(product.getStartTime()); } if(!ObjectUtils.isEmpty(product.getEndTime())){ criteria.lte(product.getEndTime()); } } //下面的写法报错:Due to limitations of the org.bson.Document, you can't add a second 'create_time' expression specified as 'create_time : Document{{$lte=Thu Jun 02 12:08:00 CST 2022}}'. // Criteria already contains 'create_time : Document{{$gte=Sun May 29 12:08:00 CST 2022}}'. // if(!ObjectUtils.isEmpty(product.getStartTime())){ // criteria = criteria.and("create_time").gte(product.getStartTime()); // } // if(!ObjectUtils.isEmpty(product.getEndTime())){ // criteria = criteria.and("create_time").lte(product.getEndTime()); // } Query query = Query.query(criteria); //排序规则 根据分类倒叙,排序升序 query.with(Sort.by( Sort.Order.desc("category"), Sort.Order.asc("sort") )); List<Product> list=mongoTemplate.find(query,Product.class); return list; }

方式二:

/** * 时间范围检索 * @param product * @return */ @RequestMapping("/findInfoByTime1") public List<Product> testTimeRange(@RequestBody Product product){ Query query = new Query(); ArrayList<Criteria> list = new ArrayList<Criteria>(); if(!ObjectUtils.isEmpty(product.getStartTime())){ list.add(Criteria.where("create_time").gte(product.getStartTime())); } if(!ObjectUtils.isEmpty(product.getEndTime())){ list.add(Criteria.where("create_time").lte(product.getEndTime())); } Criteria[] arr = new Criteria[list.size()]; if (arr.length > 0){ list.toArray(arr); Criteria criteria = new Criteria().andOperator(arr); query.addCriteria(criteria); } //排序规则 根据分类倒叙,排序升序 query.with(Sort.by( Sort.Order.desc("category"), Sort.Order.asc("sort") )); List<Product> productList=mongoTemplate.find(query,Product.class); return productList; } 三、去重排序查询

使用mongoTemplate去重排序查询:

第一种,使用mongoTemplate.findDistinct去重,不支持排序,即使你的query条件带sort排序方法。 mongoTemplate.findDistinct去重,会使排序失效。 优点:查询效率高 缺点:只返回单一字段。不可多字段返回。不能使用排序,不推荐使用

String id ="111"; Query query = new Query(); query.addCriteria(Criteria.where("_id").is(id)).with(Sort.by(Sort.Order.desc("create_time"))); List<Product> list = mongoTemplate.find(query, Product.class); List<Product> activeCodes = mongoTemplate.findDistinct(query, "name", "product",Product.class, Product.class);

第二种,使用mongoTemplate.aggregate去重,支持排序。推荐使用 优点:可指定返回类型。支持排序 缺点:排序是查询效率会变的非常低

//根据 "category","create_time" 去重统计 使用mongoTemplate.aggregate去重,支持排序。推荐使用 优点:可指定返回类型。支持排序 缺点:排序是查询效率会变的非常低 Aggregation agg = Aggregation.newAggregation( // 挑选所需的字段,类似select *,*所代表的字段内容 Aggregation.project("title", "category","sale_num","create_time"), // sql where 语句筛选符合条件的记录 Aggregation.match(criteria), // 分组条件,设置分组字段 Aggregation.group("category","create_time") //first,as里最后包含展示的字段 .first("title").as("title") .first("category").as("category") .first("sale_num").as("sale_num") .first("create_time").as("create_time") , // 排序(根据某字段排序 倒序) Aggregation.sort(Sort.by( Sort.Order.desc("create_time") )), // 重新挑选需要字段(上面 as 后的 字段) Aggregation.project("title", "category","sale_num"), //分页 Aggregation.skip((long) (Page > 0 ? (Page - 1) * pageSize : 0)), Aggregation.limit(pageSize) ); AggregationResults<Product> results = mongoOperations.aggregate(agg, "product", Product.class); List<Product> list= results.getMappedResults();

根据某字段去重统计(分组统计) Aggregation 分组、分页

/** * 根据某字段去重统计(分组统计) Aggregation 分组、分页 * @return */ @RequestMapping("/findDistinctInfo") public Map<String,Object> findDistinctInfo(@RequestParam("page") Integer Page,@RequestParam("pageSize") Integer pageSize){ Map<String,Object> resultMap = new HashMap<>(); //从mongodb里获取最新的一条记录 Criteria criteria = new Criteria(); //根据 "category","create_time" 去重统计 使用mongoTemplate.aggregate去重,支持排序。推荐使用 优点:可指定返回类型。支持排序 缺点:排序是查询效率会变的非常低 Aggregation agg = Aggregation.newAggregation( // 挑选所需的字段,类似select *,*所代表的字段内容 Aggregation.project("title", "category","sale_num","create_time"), // sql where 语句筛选符合条件的记录 Aggregation.match(criteria), // 分组条件,设置分组字段 Aggregation.group("category","create_time") //first,as里最后包含展示的字段 .first("title").as("title") .first("category").as("category") .first("sale_num").as("sale_num") .first("create_time").as("create_time") , // 排序(根据某字段排序 倒序) Aggregation.sort(Sort.by( Sort.Order.desc("create_time") )), // 重新挑选需要字段(上面 as 后的 字段) Aggregation.project("title", "category","sale_num"), //分页 Aggregation.skip((long) (Page > 0 ? (Page - 1) * pageSize : 0)), Aggregation.limit(pageSize) ); AggregationResults<Product> results = mongoOperations.aggregate(agg, "product", Product.class); List<Product> list= results.getMappedResults(); //统计去重后的 总个数 Aggregation aggregation = Aggregation.newAggregation(Aggregation.match(criteria), //按"category","create_time" 多字段分组去重统计 Aggregation.group("category","create_time").first("category").as("category") ); AggregationResults<Map> aggregate = mongoTemplate.aggregate(aggregation, Product.class, Map.class); resultMap.put("total",aggregate.getMappedResults().size()); resultMap.put("list",list); return resultMap; }

返回结果:

{ "total": 14, "list": [ { "id": "{\"category\": \"文具\", \"create_time\": \"2022-06-04 12:10:00\"}", "title": "乐普升修正带学生用笔形涂改带实惠装", "price": null, "category": "文具", "specification": null, "saleNum": 345, "sort": null, "remark": null, "createTime": null, "updateTime": null, "status": null, "startTime": null, "endTime": null } ] } 四、组合排序 Criteria criteria = new Criteria(); Query query = Query.query(criteria); //排序规则 根据分类倒叙,排序升序 query.with(Sort.by( Sort.Order.desc("category"), Sort.Order.asc("sort") )); 五、分页查询

1.普通的分页

/** * 分页获取数据列表 * @param page 当前页数 * @param pageSize 每页显示数量 * @return */ @RequestMapping("/findInfoByPage") public Map<String,Object> findInfoByPage(@RequestParam("page") Integer page,@RequestParam("pageSize") Integer pageSize){ Map<String,Object> result = new HashMap<>(); Criteria criteria = new Criteria(); Query query = Query.query(criteria); //排序规则 根据分类倒叙,排序升序 query.with(Sort.by( Sort.Order.desc("category"), Sort.Order.asc("sort") )); //获取总个数 Long count = mongoTemplate.count(query,Product.class); //分页 PageRequest pageRequest = PageRequest.of(page-1,pageSize); //分页=== 也可以用 query.skip(当前页-1).limit(页的大小) query.with(pageRequest); List<Product> list=mongoTemplate.find(query,Product.class); result.put("total",count); result.put("list",list); return result; }

2.分组分页

//从mongodb里获取最新的一条记录 Criteria criteria = new Criteria(); //根据 "category","create_time" 去重统计 使用mongoTemplate.aggregate去重,支持排序。推荐使用 优点:可指定返回类型。支持排序 缺点:排序是查询效率会变的非常低 Aggregation agg = Aggregation.newAggregation( // 挑选所需的字段,类似select *,*所代表的字段内容 Aggregation.project("title", "category","sale_num","create_time"), // sql where 语句筛选符合条件的记录 Aggregation.match(criteria), // 分组条件,设置分组字段 Aggregation.group("category","create_time") //first,as里最后包含展示的字段 .first("title").as("title") .first("category").as("category") .first("sale_num").as("sale_num") .first("create_time").as("create_time") , // 排序(根据某字段排序 倒序) Aggregation.sort(Sort.by( Sort.Order.desc("create_time") )), // 重新挑选需要字段(上面 as 后的 字段) Aggregation.project("title", "category","sale_num"), //分页 Aggregation.skip((long) (Page > 0 ? (Page - 1) * pageSize : 0)), Aggregation.limit(pageSize) ); AggregationResults<Product> results = mongoOperations.aggregate(agg, "product", Product.class); List<Product> list= results.getMappedResults();


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #Aggregate #去重