定时任务删除MongoDB历史数据

前言

MongoDB数据过多,导致存储成本飙升,为了降低成本,需要将历史数据删除。

删除逻辑

添加配置文件控制删除逻辑

XML 复制代码
syncconfig:
  deleteMongoConfig:
    #同步状态,true同步,false不同步
    syncStatus: true
    #删除数据的时间,一个月前
    deleteDays: 31
    #分布式锁key
    lockRedisKey: order.sync.deleteMongo
    #每次删除数量
    limit: 2

配置类

java 复制代码
@ConfigurationProperties(prefix = "syncconfig")
@Configuration
@RefreshScope
@Data
public class SyncConfig {
    private DeleteMongoDto deleteMongoConfig;

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class DeleteMongoDto {
        /**
         * 同步状态,true同步,false不同步
         */
        Boolean syncStatus = false;
        /**
         * 删除的天数(createTime)
         */
        Integer deleteDays = 186;
        /**
         * locakRedisKey,用于做分布式锁,防止定时任务执行时间较长,两个任务重叠执行
         */
        String lockRedisKey;
        /**
         * 每次数量
         */
        Integer limit = 1000;
    }
}

核心代码

java 复制代码
    @PostMapping("/deleteMongo")
    public BaseResponse<String> deleteMongo() {
        return orderService.deleteMongo();
    }
java 复制代码
 @Override
    public BaseResponse<String> deleteMongo() {
        //获取配置信息
        SyncConfig.DeleteMongoDto deleteMongoDto = syncConfig.getDeleteMongoConfig();
        //判断同步是否开启
        if (deleteMongoDto == null || !deleteMongoDto.getSyncStatus()) {
            log.info("deleteMongosyncStatus=false,not sync");
            return ResponseUtils.success("deleteMongosyncStatus=false,not sync");
        }
        Boolean lockStatus = false;
        try {
            lockStatus = redisLockService.acquireLock(deleteMongoDto.getLockRedisKey());
            if (!lockStatus) {
                log.info("deleteMongo get lock fail,not sync");
                return ResponseUtils.fail("deleteMongo get lock fail,not sync");
            }
            //根据时间获取orderId
            Long orderId = getOrderId(deleteMongoDto.getDeleteDays());
            Query query = new Query(Criteria.where("orderId").lt(orderId));
            query.limit(deleteMongoDto.getLimit());
            // 使用投影来只选择orderId字段
            query.fields().include("orderId");
            // 这里不用分页是因为分页会查询total效率较低,数据量大的时候耗费资源
            /*Pageable pageable = PageRequest.of(0, deleteMongoDto.getLimit());
            Page<orderDao> page = orderDao.findByOrderIdLessThan(orderId, pageable);
            List<Order> list = page.getContent();*/
            List<Order> list=mongoTemplate.find(query,Order.class);
            for (Orderitem :
                    list) {
                orderDao.deleteById(item.getOrderId());
            }
            int count = 0;
            if (CollectionUtils.isNotEmpty(list)) {
                count = list.size();
            }
            return ResponseUtils.success("deleteMongo success,count:" + count);
        } catch (Exception ex) {
            log.error("deleteMongo Exception:" + ex.getMessage());
            return ResponseUtils.fail(ex.getMessage());
        } finally {
            //释放分布式锁
            if (lockStatus) {
                redisLockService.releaseLock(deleteMongoDto.getLockRedisKey());
            }
        }
    }
    //生成半年前的orderId
    private Long getOrderId(Integer deleteDays) {
        LocalDateTime deleteTime = LocalDateTime.now().minusDays(deleteDays);
        // 将LocalDateTime转换为毫秒值
        ZonedDateTime utcZonedDateTime = deleteTime.atZone(ZoneId.systemDefault());
        long milliseconds = utcZonedDateTime.toInstant().toEpochMilli();
        Long orderId = (milliseconds / 1000) << 32;
        return orderId;
    }

总结

这里是简单的删除历史数据逻辑,可以参考执行,分布式锁是为了防止重复调用,实际使用的时候也可以不用分布式锁。然后定时调用这个删除接口即可不断的删除历史数据了

相关推荐
临床数据科学和人工智能兴趣组几秒前
正则表达式的基础语法的常用字符类
数据库·r语言·r语言-4.2.1·临床研究·临床试验
鱼很腾apoc3 分钟前
【MySQL】 第2期 查询与函数系统详解:从基础 CRUD 到复合多表查询
linux·数据库·学习·mysql·dml
前端 贾公子27 分钟前
LangGraph == 图的状态(State)管理 (下)
运维·服务器·数据库
zlwool37 分钟前
机械行业ERP与进销存的合规选型边界
数据库·erp
梦想的颜色42 分钟前
【AI速览】RAG 向量数据库选型:Milvus、Chroma、Qdrant、PGVector 全维度横向对比
数据库·milvus·chroma·rag·pgvector·向量库·qdrant
小溪学编程1 小时前
向量数据库 Milvus 基础实践:从入门到上手
数据库·milvus
数据最前线1 小时前
雪上加霜,Oracle向蓝色巨人最后的阵地发起挑战
数据库·oracle
于眠牧北1 小时前
Charles配置指定域名抓取和雷电模拟器中抓取APP接口配置
数据库·redis·缓存
福娃筱欢2 小时前
57014 canceling statement due to user request(金仓 KingbaseES)
数据库·kingbase·金仓数据库
ClouGence2 小时前
SAP HANA 数据同步遇到长事务,如何兼顾实时性与完整性?
数据库·后端