【Springboot系列】项目启动时怎么给mongo表加自动过期索引

1、前言

在之前操作mongo的过程中,都是自动创建,几乎没有手动创建过表。

这次开发中有张表数据量大,并且不是特别重要,数据表维护一个常见的问题是过期数据没有被及时清理,导致数据量过大,查询变得缓慢。为了解决这个问题,我们可以通过创建过期索引来定期清理过期数据。

数据过期的原理可以看下之前的文章:我屮艸芔茻,mongo居然可以自动删除数据

2、直接上代码

逻辑很简单,在服务器启动之后去检查索引

  • 1.先检查存不存在这个索引
  • 2.然后创建索引
  • 3.在每个entity中增加了一个save_time的字段
java 复制代码
package com.tyjt.ccpparking.mgr;
 
import com.tyjt.ccpparking.domain.entity.ParkingHBEntity;
import com.tyjt.ccpparking.domain.entity.ParkingRestInfoEntity;
import com.tyjt.ccpparking.msg.EmqxHBHandler;
import com.tyjt.ccpparking.service.ParkingService;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.index.Index;
import org.springframework.data.mongodb.core.index.IndexDefinition;
import org.springframework.data.mongodb.core.index.IndexInfo;
import org.springframework.stereotype.Component;
 
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
 
@Component
@Data
public class Mgr implements ApplicationRunner {
    private static Logger logger = LoggerFactory.getLogger(Mgr.class);
    @Resource
    MongoTemplate mongoTemplate;
 
    public Mgr() {
        mgr = this;
    }
 
    private static Mgr mgr;
 
    public static Mgr getInstance() {
        return mgr;
    }
 
 
    @Override
    public void run(ApplicationArguments args) throws Exception {
        createMongoIndex(ParkingHBEntity.class);
        createMongoIndex(ParkingRestInfoEntity.class);
    }
 
    /**
     * 创建mongo的索引
     *
     * @param clazz
     */
    public void createMongoIndex(Class clazz) {
        try {
            if (isIndexExists(clazz)) {
                return;
            }
            Index index = new Index();
            index.on("save_time", Sort.Direction.DESC);
            index.expire(7, TimeUnit.DAYS);
            mongoTemplate.indexOps(clazz).ensureIndex(index);
        } catch (Exception e) {
            logger.error("create index fail {}", clazz.getName(), e);
        }
    }
 
    public boolean isIndexExists(Class clazz) {
        List<IndexInfo> indexInfos = mongoTemplate.indexOps(clazz).getIndexInfo();
        for (IndexInfo indexInfo : indexInfos) {
            if ("save_time_-1".equals(indexInfo.getName())) {
                return true;
            }
        }
        return false;
    }
}

注:这里可以直接接写collection name,

也可以使用实体的class,因为mongo的entity的注解有@Document(collection = "parking_HB")

注:在删除表的时候也会删除索引

mongodb使用后台线程定时做超时数据的清理工作,因此,数据清理并不及时,清理的时间间隔大概在几十秒,所以,如果对超时时间要求比较严格的场景,比如:验证码之类的,就不能百分之百信任这个超时时间。

TTL索引只能在单字段上建立,并且字段类型必须是date类型或者包含有date类型的数组(如果数组中包含多个date类型字段,则取最早时间为过期时间)

3、TTL索引使用限制条件

以下几种情况无法使用TTL索引: ① TTL索引是单字段索引,混合索引不支持TTL,并且也会忽略expireAfterSeconds属性。

② 在_id 主键上不能建立TTL索引。

③ 在capped collection中不能建立TTL索引,因为MongoDB不能从capped collection中删除文档。

④ 不能使用createIndex()去更改已经存在的TTL索引的expireAfterSeconds值。如果想更改expireAfterSeconds,可以使用collMod命令;否则,只能删除索引,然后重建。

⑤ 不能在已有索引的字段上再创建TTL索引了。如果想把非TTL索引改为TTL索引,那就只能先删除非TTL索引,然后新建TTL索引。

4、总结

在Mongo数据库中创建过期索引,定期清理过期数据以保证数据的质量和性能。

创建过期索引可以大大简化过期数据的清理过程,并且可以帮助我们避免在查询和数据分析时出现问题。

同时,定期清理过期数据可以提高查询和分析的效率,保证系统的性能。

希望本文对您在Mongo数据库管理和维护方面有所帮助。如果您有任何问题或建议,请在下方留言区留言,我将尽快回复

相关推荐
武子康7 分钟前
Search Console Platform Properties 扩大 SEO 资产边界:从 Page Ranking 到 Topic Coverage(5 类误读边界 + 3 表数据层设计)
前端·人工智能·后端
腾渊信息科技公司1 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
IT_陈寒2 小时前
Vue这个特性差点让我加班到凌晨,谁懂啊
前端·人工智能·后端
段一凡-华北理工大学2 小时前
向量数据库实战:选型、调优与落地~系列文章12:文本分块策略实战:chunk_size 怎么选?重叠多少?
开发语言·数据库·后端·oracle·rust·工业智能体·高炉智能化
码事漫谈3 小时前
1999年的电商前夜和2026年的AI前夜 历史押韵但从不重复
后端
Conan在掘金3 小时前
鸿蒙报错速查:arkts-strict-typing Property does not exist on type 'object',object 装函数就炸,根因 + 真解法
后端
颜酱3 小时前
01 | 骨架搭建:FastAPI + Vue 跑通第一个 SSE 流式问答
前端·人工智能·后端
程序员cxuan4 小时前
Grok Build 被众人唾骂,结果老马把它开源了
人工智能·后端·程序员
从零开始的代码生活_4 小时前
C++ 继承详解:访问控制、对象模型、菱形继承与设计取舍
开发语言·c++·后端·学习·算法
Conan在掘金5 小时前
�鸿蒙报错速查:Cannot find name 'require',禁用 require(),根因 + 真解法
后端