'Mongoose Schema set an expires on field to delete document?
I want to delete the document after 3 min it's been created. The field that defines the moment the document is created is expiresAt. This is the set up I have thus far. The document does not delete after 3 min as it should.
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const PostsAmountsTimeframesSchema = new Schema({
posts_amounts_timeframe: Number,
expireAt: {
type: Date,
default: new Date()
},
userid: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true
},
})
PostsAmountsTimeframesSchema.index( { expireAt: 1 }, { expireAfterSeconds: 180 } )
const PostsAmountsTimeframes = mongoose.model('PostsAmountsTimeframes', PostsAmountsTimeframesSchema)
module.exports = PostsAmountsTimeframes
Also tried
expireAt: {
type: Date,
default: new Date(),
expires: 180,
}
same result.
PS: this is how the document is created on the server:
PostsAmountsTimeframes.create({
userid: req.session.userId,
posts_amounts_timeframe: req.session.posts_amounts_timeframe,
// expireAt: d
}, (error, postsamountstimeframes) => {
console.log(error)
})
Solution 1:[1]
This code should work:
const PostsAmountsTimeframesSchema = new Schema({
posts_amounts_timeframe: Number,
expireAt: {
type: Date,
expires: "3m", default: Date.now
},
userid: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true
},
})
Solution 2:[2]
Solution
- Delete entire collection
- Delete all indexes you have on the collection
- Change code to this:
const mongoose = require('mongoose')
//Create empty Schema object?
const Schema = mongoose.Schema
//Models are defined through the Schema interface
//Models define collections
const PostsAmountsTimeframesSchema = new Schema({
posts_amounts_timeframe: Number,
expireAt: {
type: Date,
},
userid: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true
},
})
PostsAmountsTimeframesSchema.index({ expireAt: 1 }, { expireAfterSeconds: 0 });
//Access the database my_database via mongoose.model.
//The first argument: The name of the collection the model is for.
//Apply the model to the collection?
const PostsAmountsTimeframes = mongoose.model('PostsAmountsTimeframes', PostsAmountsTimeframesSchema)
//Export User variable to other files
module.exports = PostsAmountsTimeframes
Use this to create entry. I used 3 min after current date to expire collection.
var d = new Date()
d.setMinutes(d.getMinutes()+3);
var r = new Date(d)
PostsAmountsTimeframes.create({
userid: req.session.userId,
posts_amounts_timeframe: req.session.posts_amounts_timeframe,
expireAt: r
}, (error, postsamountstimeframes) => {
console.log(error)
})
- Close mongosh
- Close Mongo Compass
- Rebuild project
- Rerun project
- Create an entry and Bam! It will auto delete itself upon creation of an entry.
There should be a way to do same thing with expires TTL. Working on that method currently!
Solution 3:[3]
I recently have to create an TTL index using mongoose (cf. gist). I didn't play with "default" option, but I think that your example should work
expireAt: {
type: Date,
default: new Date(),
expires: 180,
}
This code with "expires" will create for you a mongo TTL index with "expireAfterSeconds" : 180 which is what you want to achieve.
Mongo TTL index will consider that the document is expired after expireAt value + expireAfterSeconds seconds.
One point you didn't talk about is the way mongo will finaly remove the expired entries : the background mongo job will takes between 0 and 60 seconds to detect and remove them: cf mongo doc :
The background task that removes expired documents runs every 60 seconds. As a result, documents may remain in a collection during the period between the expiration of the document and the running of the background task.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | r_dmr |
| Solution 2 | |
| Solution 3 | boly38 |
