代码之家  ›  专栏  ›  技术社区  ›  jlyh

MongoDB TTL到期在NodeJS上无法正常工作

  •  1
  • jlyh  · 技术社区  · 7 年前

    我使用MongoDB(v3.4)作为缓存,并使用TTL索引使记录过期。然而,TTL设置似乎无法正常工作。具体来说,我使用端点插入数据进行了测试(如下所示)。

    端点mongoInsert应该在5分钟内过期。但是,似乎在大约1分钟后,文档被删除了。我还查阅了其他关于使用UTC时间using moment()的类似建议。utc()。toDate(),行为也一样。new Date()返回UTC时间,所以我想应该是相同的效果。

    不确定是否应该包括其他设置,但文档中没有详细说明。以前有人遇到过这种情况吗?

    function mongoInsert(mongoClient){
        return function(req, res){
            mongoClient.connect('mongodb://localhost:27017/cache', function(err, db) {
                db.collection('data', function(err, collection){
                    var testItems = [{
                        "_id": "abc12345",
                        "dmac": "abc",
                        "createdAt": new Date(),
                        "val": {
                            "0": 10,
                            "1": 15,
                            "2": 5
                        },
                        "res": "minutes",
                        "time": "2017-12-04T00:12:58Z"
                    }];
                    let unix = new moment().valueOf();
                    collection.createIndex({createdAt: unix}, {expireAfterSeconds: 300});
                    collection.insertMany(testItems, function(err, items){
                        db.close();
                        res.json(items);
                    });
                })
            })
        }
    }
    
    1 回复  |  直到 7 年前
        1
  •  3
  •   jlyh    7 年前
    collection.createIndex({createdAt: 1}, {expireAfterSeconds: 60,unique:true});
    

    collection.createIndex({createdAt: 1}, {expireAfterSeconds: 300,unique:true});
    

    这是无效的

    不能使用createIndex()更改现有索引的expireAfterSeconds值。而是将collMod数据库命令与索引集合标志结合使用。否则,要更改现有索引选项的值,必须先删除该索引,然后重新创建。

    https://docs.mongodb.com/v3.4/core/index-ttl/

    对于个别文档的过期,有报告称,只有通过计算过期时间并按特定时钟时间将其过期才能完成(参考:groups.google.com/forum/#!topic/mongodb-dev/ZLb8KSrLyOo)。

    var testItems = [{
        "_id": "abc12345",
        "dmac": "abc",
        "expireAt": moment().add(3, 'minutes').toDate(),
        "val": {
            "0": 10,
            "1": 15,
            "2": 5
        },
        "res": "minutes",
        "time": "2017-12-04T00:12:58Z"
    }];
    let unix = new moment().valueOf();
    collection.createIndex({expireAt: unix}, {expireAfterSeconds: 0}, function(error, indexName){
        if(error) console.log(error);
        console.log(indexName);  
    });