跳到主要内容

时间维度查询条件的执行

在实时查询采集后的指标数据功能中,是支持多种维度的,首先分为两大类:

  • 视频分类的维度:一级分类、二级分类、视频本身
  • 时间分类的维度:天、周、月、年

这两种类型维度的可以随意的相互搭配,比如:

  • 一级分类下的天查询
  • 一级分类下的月查询
  • 二级分类下的天查询
  • 二级分类下的月查询
  • ... ...

都是可以支持的,怎么搭配都是可以的,而这些搭配调用的都是同一套执行的方法流程,也就是说此查询指标数据方法的扩展性是非常高的!

查询时间范围

在查询指标数据时,有个非常重要的查询条件,当选择了天、周、月、年的维度后,就会相应对应维度下的时间范围

按天查询

按天查询

按周查询

按周查询

按月查询

按月查询

按年查询

按年查询

API入口

@Operation(summary  = "查询时间范围数据")
@PostMapping(value = "/date/range/query")
public ApiResponse<List<DateRangeQueryVo>> dateRangeQuery(@Valid @RequestBody DataTypeQueryDto dataTypeQueryDto) {
return ApiResponse.ok(collectService.dateRangeQuery(dataTypeQueryDto));
}
public List<DateRangeQueryVo> dateRangeQuery(DataTypeQueryDto dataTypeQueryDto) {
QueryDateTimeHandler queryDateTimeHandler = Optional.ofNullable(queryDateTimeHandlerContext.getQueryDateHandler(
dataTypeQueryDto.getDateType())).orElseThrow(() -> new DockDataCenterFrameException(BaseCode.DATE_TYPE_NOT_EXIST));
return queryDateTimeHandler.assembleDateTime();
}

这个结构依然是熟悉的策略模式,将天、周、月、年的时间维度划分成了不同的策略

时间策略的定义

首先要定义时间策略的行为,包括:组装日志时间、日期类型

public interface QueryDateTimeHandler {
/**
* 组装日期时间
* @return 日期范围查询视图对象列表
*/
List<DateRangeQueryVo> assembleDateTime();

/**
* 日期类型
* @return 日期类型整数
*/
Integer dateType();
}

时间策略的上下文

依旧要有上下文容器,将所有QueryDateTimeHandler的实现策略,放到容器中

@Component
public class QueryDateTimeHandlerContext {

@Autowired
private List<QueryDateTimeHandler> queryDateTimeHandlerList;

private Map<Integer, QueryDateTimeHandler> queryDateHandlerMap = new HashMap<>();

@PostConstruct
public void init(){
queryDateHandlerMap = queryDateTimeHandlerList.stream().collect(Collectors.toMap(
QueryDateTimeHandler::dateType,
handler -> handler,
(existing, replacement) -> existing));
}

public QueryDateTimeHandler getQueryDateHandler(Integer dateType) {
return queryDateHandlerMap.get(dateType);
}
}

利用了Spring的加载bean的方式,当服务启动后,会执行Spring中的@PostConstruct修饰的方法init,获取所有QueryDateTimeHandler类型的queryDateTimeHandlerList集合

接着将此集合转成queryDateHandlerMap也就是Map结构,key: 时间类型, value: 时间策略处理器

提供了getQueryDateHandler能够根据dateType日期类型从queryDateHandlerMap获取具体的时间查询实现策略

QueryDateTimeHandler的实现有:

  • QueryDayDateTimeHandler: 查询按天的时间处理器
  • QueryWeekDateTimeHandler: 查询按周的时间处理器
  • QueryMonthDateTimeHandler: 查询按月的时间处理器
  • QueryYearDateTimeHandler: 查询按年的时间处理器

查询按天的时间处理器

@Component
public class QueryDayDateTimeHandler implements QueryDateTimeHandler {

private static final Integer DAY_SIZE = 30;

@Override
public List<DateRangeQueryVo> assembleDateTime() {
List<DateRangeQueryVo> dateRangeQueryVoList = new ArrayList<>();
Date yesterdayDate = DateUtils.addDay(DateUtils.now(), -1);
Date start = new Date(0L);
Date tempDate = yesterdayDate;
for (int i = 0; i < DAY_SIZE; i++) {
DateRangeQueryVo dateRangeQueryVo = new DateRangeQueryVo();
String startDate = DateUtils.format(tempDate, DateUtils.FORMAT_DATE);
String endDate = DateUtils.format(tempDate, DateUtils.FORMAT_DATE);
dateRangeQueryVo.setStartDate(startDate);
dateRangeQueryVo.setEndDate(endDate);
dateRangeQueryVo.setRangeDateName(startDate + " ~ " + endDate);
dateRangeQueryVo.setDateType(DateType.DAY.getCode());
dateRangeQueryVoList.add(dateRangeQueryVo);
// 如果当前时间超出最小时间限制退出循环
if(tempDate.before(start)) {
break;
}
// 得到下一个要处理的时间(得到向前的一天,i + 1 是为了每次是根据 yesterdayDate 得到向前的天数
tempDate = DateUtils.obtainBeforeDate(yesterdayDate, i + 1);
}
return dateRangeQueryVoList;
}

@Override
public Integer dateType() {
return DateType.DAY.getCode();
}
}

方法意图

  • 构造“按天”维度的查询时间段清单:从“昨天”开始,最多向前回溯 DAY_SIZE(30)天,每天一条。
  • 每条时间段是单天区间:startDate == endDate,并带有展示名 startDate ~ endDate 和日期类型标记为“天”。

执行流程分解

付费内容提示

该文档的全部内容仅对「码力全开」项目实战&技术讲解 知识星球用户开放

加入星球,一次获得完整项目资料、全栈技术知识库和长期答疑服务。

100万+字全栈技术知识库深入讲解技术核心、数据库、中间件和分布式等内容
8套热门的实战项目持续更新的企业级项目覆盖高并发、微服务、数据中台 和 AI Agent 等方向
AI 技术知识大模型面试详解覆盖 AI 模型原理、Agent、RAG、MCP、Skills、Harness 等核心知识点
文档 + 视频两种讲解形式既能系统阅读,也能跟随视频理解核心业务

完整项目实战资料

每套项目均包含从 0 到 1 讲解文档核心业务讲解视频

从基础项目到复杂业务场景,项目资料会持续更新。

8 套项目
  • 01Nexus Agent AI 智能体
  • 02Nexus Agent Pro 完全版
  • 03黑马点评Plus
  • 04大麦
  • 05大麦Pro
  • 06大麦AI
  • 07流量切换
  • 08数据中台

加入后还能获得

进入星球后,即可享受上述所有服务,保证不会再有其他隐藏费用。

从学习、面试到项目启动,都可以继续获得支持。

  • 1 对 1 解答项目和技术问题都可以提问
  • 针对性补充没有讲清楚的内容会继续补充
  • 面试与简历指导梳理回答技巧和项目亮点
  • 中间件云环境项目依赖可以直接接入使用
  • 面试后复盘被问住的问题可以继续交流
  • 远程问题解决项目启动问题可协助排查
知识星球二维码

扫码进入知识星球

  1. 打开微信,扫描左侧二维码,加入「码力全开」项目实战&技术讲解 知识星球
  2. 查看星球使用指导,获取完整项目讲解资料索引
解锁全部付费内容
🎁优惠