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

相关推荐
李梨同学丶26 分钟前
0201好虫子周刊
后端
思想在飞肢体在追36 分钟前
Springboot项目配置Nacos
java·spring boot·后端·nacos
Loo国昌3 小时前
【垂类模型数据工程】第四阶段:高性能 Embedding 实战:从双编码器架构到 InfoNCE 损失函数详解
人工智能·后端·深度学习·自然语言处理·架构·transformer·embedding
ONE_PUNCH_Ge4 小时前
Go 语言泛型
开发语言·后端·golang
良许Linux4 小时前
DSP的选型和应用
后端·stm32·单片机·程序员·嵌入式
不光头强4 小时前
spring boot项目欢迎页设置方式
java·spring boot·后端
怪兽毕设4 小时前
基于SpringBoot的选课调查系统
java·vue.js·spring boot·后端·node.js·选课调查系统
学IT的周星星5 小时前
Spring Boot Web 开发实战:第二天,从零搭个“会卖萌”的小项目
spring boot·后端·tomcat
郑州光合科技余经理5 小时前
可独立部署的Java同城O2O系统架构:技术落地
java·开发语言·前端·后端·小程序·系统架构·uni-app
Remember_9935 小时前
Spring 事务深度解析:实现方式、隔离级别与传播机制全攻略
java·开发语言·数据库·后端·spring·leetcode·oracle