SpringBoot+mongodb实现分组统计、时间范围查询、去重排序查询、组合排序
/**
* 根据分类名称 分组统计销售数量
* @param dataType 1:本日 2:本月 3:本年
* @return
*/
@RequestMapping("/findInfoByGroup")
public 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
/**
* 根据分类名称和规格 分组统计销售数量
* @param
* @return
*/
@RequestMapping("/findInfoByGroup1")
public List 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 aggregationResults = mongoTemplate.aggregate(aggregation,Product.class,Map.class);
List 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 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 list=mongoTemplate.find(query,Product.class);
return list;
}
方式二:
/**
* 时间范围检索
* @param product
* @return
*/
@RequestMapping("/findInfoByTime1")
public List testTimeRange(@RequestBody Product product){
Query query = new Query();
ArrayList list = new ArrayList();
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 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 list = mongoTemplate.find(query, Product.class);
List 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 results = mongoOperations.aggregate(agg, "product", Product.class);
List list= results.getMappedResults();
根据某字段去重统计(分组统计) Aggregation 分组、分页
/**
* 根据某字段去重统计(分组统计) Aggregation 分组、分页
* @return
*/
@RequestMapping("/findDistinctInfo")
public Map findDistinctInfo(@RequestParam("page") Integer Page,@RequestParam("pageSize") Integer pageSize){
Map 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 results = mongoOperations.aggregate(agg, "product", Product.class);
List list= results.getMappedResults();
//统计去重后的 总个数
Aggregation aggregation = Aggregation.newAggregation(Aggregation.match(criteria),
//按"category","create_time" 多字段分组去重统计
Aggregation.group("category","create_time").first("category").as("category")
);
AggregationResults 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 findInfoByPage(@RequestParam("page") Integer page,@RequestParam("pageSize") Integer pageSize){
Map 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 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 results = mongoOperations.aggregate(agg, "product", Product.class);
List list= results.getMappedResults();
先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦