按日期分组
Aggregation aggregation2 = Aggregation.newAggregation(
Aggregation.match(Criteria.where("type").is(VisitRecordByDay.TYPE_SHOW_WEI_BASE_VISIT)),
Aggregation.group().sum("time").as("count")
);
/**
* 获取指定时间段的数据,按日期统计数量
*
* @param field 按数据库中哪个字段统计
* @param startTimestamp 开始时间戳
* @param endTimestamp 结束时间戳
* @param format 格式化时间,%Y-%m-%d 按天,%Y-%m 按月
* @return List<CountVo>
*/
public List<CountVo> getListDate(String field, Date startTimestamp, Date endTimestamp, String format, String collectionName, Criteria criteria) {
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.match(Criteria.where(field).gte(startTimestamp).lt(endTimestamp).andOperator(criteria)),
Aggregation.project(field).and(DateOperators.DateToString.dateOf(field).toString(format)).as("date"),
Aggregation.group("date").count().as("count"),
Aggregation.project("date", "count").and("date").previousOperation(),
Aggregation.sort(Sort.Direction.ASC, "date")
);
return mongoTemplate.aggregate(aggregation, collectionName, CountVo.class).getMappedResults();
}
/**
* 获取指定时间段的数据,按某字段数量和统计
*/
public List<CountVo> getListDateForSum(String field, Date startTimestamp, Date endTimestamp, String format, String collectionName, Criteria criteria, String sumFieldName) {
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.match(Criteria.where(field).gte(startTimestamp).lt(endTimestamp).andOperator(criteria)),
Aggregation.project(field, sumFieldName).and(DateOperators.DateToString.dateOf(field).toString(format)).as("date"),
Aggregation.group("date").count().as("count2").sum(sumFieldName).as("count"),
Aggregation.project("date", "count").and("date").previousOperation(),
Aggregation.sort(Sort.Direction.ASC, "date")
);
return mongoTemplate.aggregate(aggregation, collectionName, CountVo.class).getMappedResults();
}
时区差8小时
根据时间统计会出现
Aggregation.project().andExpression("add(createTime," + 8 * 60 * 60 * 1000 + ")").as("newDate")
统计表中所有数据某字段相加
Aggregation.group().sum("time").as("count")
日期补全
使用的是hutool工具包做底层支持
/**
* 补全一个月的所有天
*
* @param dateList 原数据
* @param startTimestamp 开始时间戳
* @param endTimestamp 结束时间戳
* @return List<CountVo>
*/
private List<CountVo> supplementMonth(List<CountVo> dateList, long startTimestamp, long endTimestamp) {
// 今日之后不显示
if (endTimestamp > new Date().getTime()) {
endTimestamp = new Date().getTime();
}
long stride = 24 * 60 * 60 * 1000; // 步长
ArrayList<CountVo> listDate = new ArrayList<>();
for (long newTime = startTimestamp; newTime <= endTimestamp; newTime += stride) {
String formatDate = DateUtil.format(new Date(newTime), "yyyy-MM-dd");
boolean isFind = false;
for (CountVo countVo : dateList) {
if (formatDate.equals(countVo.getDate())) {
listDate.add(countVo);
isFind = true;
break;
}
}
if (!isFind) {
listDate.add(new CountVo(formatDate, 0L));
}
}
return listDate;
}
/**
* 补全一年的所有月份
*
* @param dateList 原数据
* @param startDate 一年开始时间
* @return List<CountVo>
*/
private List<CountVo> supplementYear(List<CountVo> dateList, Date startDate) {
ArrayList<CountVo> listDate = new ArrayList<>();
for (int i = 0; i < 12; i++) {
Date monthDate = DateUtil.offsetMonth(startDate, i);
// 本月之后不显示
if (monthDate.getTime() > new Date().getTime()) {
break;
}
String formatDate = DateUtil.format(monthDate, "yyyy-MM");
boolean isFind = false;
for (CountVo countVo : dateList) {
if (formatDate.equals(countVo.getDate())) {
listDate.add(countVo);
isFind = true;
break;
}
}
if (!isFind) {
listDate.add(new CountVo(formatDate, 0L));
}
}
return listDate;
}
日期补全CountVo
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CountVo {
private String date;
private long count;
}