Reputation: 409
I have the following Schema for a virtual classroom in mongoose:
var classroomSchema = mongoose.Schema({
studentIds: [mongoose.Schema.Types.ObjectId],
teacherIds: [mongoose.Schema.Types.ObjectId],
teacherNames: [String],
createdAt: {
type: Date,
default: Date.now(),
},
lessons: [{
name: String,
startDate: {
type: Date,
min: Date.now(),
},
endDate: {
type: Date,
min: Date.now(),
},
**expiresAt: endDate,**
}],
});
I want each lesson to expire from the classroom after theer endDate has passed. How can I use TTLs in subdocuments in mongoose?
Upvotes: 1
Views: 1634
Reputation: 4619
A part of the document cannot be deleted with ttl. I can think of two other options as a workaround:
Take out lesson
to its own collection and place classroom_id
in it as reference to classroom. This way you'll be able to remove the lesson alone with ttl.
Use a scheduler like cron to run a job every few minutes/hours to find in classrooms lessons with expiry dates passed and remove them from lesson
array.
var CronJob = require('cron').CronJob;
var job = new CronJob({
cronTime: '00 */20 * * * *', //run every 20 minutes
onTick: function() {
//Find classrooms with lessons which have expiry date smaller than Date.now
//Remove those lessons from array and update the classrooms
},
start: false,
timeZone: 'America/Los_Angeles'
});
job.start();
For searching expiresAt
within array of subdocument you can use $elemMatch
operator, as shown in this example.
The only downside of method 2 is that depending on the cronjob interval you choose, lessons can persist passed their expiry dates for few extra minutes.
Upvotes: 2