Mongo创建过期索引以及为何创建了过期索引不生效?

首先描述下业务场景

     用户下单后,但是一直未支付,需要1天之后,自动删除该临时订单,这种功能有三种实现方式:

       1) 是写个定时器,每分钟扫一下临时订单表,如果存在则根据创建时间计算下是否达到了24H

       2)  每创建一个临时订单,则需要向另外一张表中写入一条数据,记录这比临时订单要删除的时间,还是定时器,扫这个时间,如果要删除的时间和当前时间大于这个时间,则删除掉临时订单

       3) 利用数据库的过期索引,自动删除

 

当然对比三种方案,还是第三种比较适合且比较简洁,不需要自己开发大量代码去维护一堆要删除的数据

数据源是mongo就不用说了,我们先写个简单的例子,来讲解下

 

1. 首先创建collection

db.createCollection("index4")

2. 在创建过期索引之前,需要拟定过期索引的key是什么,比如我这里起叫time,作为过期索引的key,那创建过期索引的语句为:

db.index4.ensureIndex({"time": 1},{expireAfterSeconds: 30})

以上索引的意思是,在collection等于index4上面,创建一个过期索引,名称为 time,过期时间为30秒

3. 查询一下刚刚创建的索引是否成功

db.index4.getIndexes()

可以看到,索引已经创建成功了,那我们创建下数据,这里我就不通过脚本创建了,我这边用java 去创建的数据,重点提一下,创建过期索引,key对应的类型必须是时间类型的,如果是时间戳,则不会生效的,java中可以用java.util.Date或者java.sql.Timestamp

以下为我的实例类:

package com.ijson.mongo.support.test.bean;

import com.ijson.mongo.support.model.BaseEntity;
import lombok.Data;
import lombok.ToString;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;

import java.sql.Timestamp;
import java.util.Date;

@Data
@Entity(value = "index4", noClassnameStored = true)
@ToString(callSuper = true)
public class IndexEntity extends BaseEntity {

    @Id
    private String id;
    /**
     * 可以修改为Timestamp
     */
    private Date time;

    private String cname;

}

下面是我的测试类,执行下保存操作

    @Test
    public void addIndex() {
        IndexEntity entity = new IndexEntity();
        entity.setId(ObjectId.getId());
        entity.setCname("zhangsan");
        entity.setTime(new Date());
        /**
         * 如果是Timestamp 需要将时间转一下
         */
//        entity.setTime(new Timestamp(System.currentTimeMillis()));
        datastore.save(entity);
    }

这个时候就可以看到我们创建了一条数据,这里注意下  time的类型针对mongo来说是  ISODate类型的,其他开发语言保存到mongo中是这样的类型就可以

接下来让我们等待30秒,这时,我们看张图片,缓解缓解工作中带来的压力,以下图片纯粹网络摘取,不认识,这是觉得很漂亮

30s过去了,查一下我们的数据,已经被清空了,很多同学手我的过期索引一直不生效,那就得看下你的字段类型是什么了,如果保存到mongo中数据类型为ISODate,那保准没问题,其他类型,特定不可以

案例在:https://github.com/ijson/in-mongo-spring-support中,搜索下MongoDBTest,看下第三个case即可

福利图摘选自:青竹壁纸

 

意见反馈

您的问题或建议:

您的联系方式:

留下您的联系方式,以便我们了解问题后及时反馈和结果,紧急问题请联系客服QQ:87501553。