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