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

相关推荐
桦说编程13 分钟前
Java 中如何创建不可变类型
java·后端·函数式编程
IT毕设实战小研16 分钟前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
wyiyiyi39 分钟前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
阿华的代码王国2 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
Jimmy2 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
AntBlack2 小时前
不当韭菜V1.1 :增强能力 ,辅助构建自己的交易规则
后端·python·pyqt
bobz9653 小时前
pip install 已经不再安全
后端
寻月隐君3 小时前
硬核实战:从零到一,用 Rust 和 Axum 构建高性能聊天服务后端
后端·rust·github
Pitayafruit5 小时前
Spring AI 进阶之路03:集成RAG构建高效知识库
spring boot·后端·llm
我叫黑大帅5 小时前
【CustomTkinter】 python可以写前端?😆
后端·python