Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose expires property not working properly

the answer

So it turns out when I was testing using the expires property in Mongoose, I successfully set a TTL index in the database, but didn't realize that when I changed the time in my mongoose schema I'd need to delete the previous TTL index out of the database first.

TLDR; - stop the app and delete the TTL index of the field you want to change (see comments / answer below)

getting indexes

Ok with the code from the below example, after calling: db.sampletexts.getIndexes() I get

[
    {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "test.sampletexts"
    },
    { 
        "v" : 1,
        "key" : {
            "createdAt" : 1
        },
        "name" : "createdAt_1",
        "ns" : "test.sampletexts",
        "expireAfterSeconds" : 5400,
        "background" : true,
        "safe" : null
    }
]

so although I'm specifying 60 seconds, its setting to 5400? huh.

second update

Heres a minimal example of what I'm trying to run. I must be missing something here because I actually copied my model from my original project to the example (minus a few extra string fields), and now the document doesn't expire at all? Please, make me feel dumb and realize I'm missing something obvious. I thought for a second to set an interval to run the time difference check between the docs and the current time, then realized how badly running that many queries that often would scale. Hmm...

MongoDB v3.0.1 && Mongoose v4.0.1

relevant code in: /routes/index.js


Some test values I've run:

with the full field looking like this

createdAt: { type: Date, expires: 3600, default: Date.now }

test 1: (tested 3x) expires: ’300s’

expired at: 2:00 && 2:50 && 2:28

test 2: (tested 2x) expires: ‘600s'

expired at: 2:08 && 2:58

test 3: expires: 600 expired at: 2:55

test 4: expires: 3600 expired at: 2:13

Update:

I'm back at it and decided since I tried a different version of MongoDB, I'd try a different version of Mongoose v3.7.4. Unfortunately I got the same result. I'm beginning to wonder if this could be an issue caused by my actual computer (I'm running on localhost)? I'm not sure how MongoDB gets/sets/monitors its DateTime, but I'm assuming that it must be getting it from my computers settings. Is there a good way I can go about testing/debugging this further?


Original Question:

Ok I've looked at a few other answers regarding expiring docs here with Mongoose and MongoDB, but they seem to be because either

a) the document isn't getting deleted

or

b) its getting deleted at a point way after it was designated to

My issue is that the document is getting deleted but after 1 minute no matter what. So when I specify a time, doesn't matter when, it deletes it after 60 seconds. I see that MongoDB runs a check every minute that removes specified docs, and its defaulted at 60 seconds, so I'm assuming that MongoDB is acknowledging the expire-able document, but not getting the TTL parameter passed, and I'm pretty stumped. Any help would be appreciated.

heres my model:

var schema = mongoose.Schema({
    user_id: String,
    message: String,
    createdAt: { type: Date, expires: '4h', default: Date.now },
    location: Object
});

Versions:

mongoose 4.0.1

mongodb 3.0.1 (also tested in 2.6.7)

like image 621
adrian_reimer Avatar asked Apr 08 '15 20:04

adrian_reimer


1 Answers

Modifying your Mongoose schema won't modify an existing index, so you need to manually drop the TTL index and restart your app to re-create the index using the current definition.

db.sampletexts.dropIndex('createdAt_1')
like image 115
JohnnyHK Avatar answered Nov 14 '22 18:11

JohnnyHK