【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数据库管理和维护方面有所帮助。如果您有任何问题或建议,请在下方留言区留言,我将尽快回复

相关推荐
烟袅6 分钟前
为什么调用 OpenAI Tools 后,还要再请求一次大模型?——从代码看 LLM 工具调用的本质
后端·python·llm
e***09619 分钟前
SpringBoot下获取resources目录下文件的常用方法
java·spring boot·后端
简创AIGC陶先生1 小时前
【剪映小助手源码精讲】09_音频素材管理系统
后端
will_we1 小时前
Spring Boot4正式篇:第二篇 多版本API特性
java·后端
v***5652 小时前
Spring Cloud Gateway
android·前端·后端
e***95642 小时前
springboot项目架构
spring boot·后端·架构
q***21602 小时前
Spring Boot项目接收前端参数的11种方式
前端·spring boot·后端
j***12152 小时前
Spring Boot与MyBatis
spring boot·后端·mybatis
optimistic_chen2 小时前
【Java EE进阶 --- SpringBoot】Spring事务传播机制
spring boot·后端·spring·java-ee·事务·事务传播机制
l***74943 小时前
SQL Server2022版+SSMS安装教程(保姆级)
后端·python·flask