lightbringer
lightbringer

Reputation: 409

How can I make a subdocument expire at a particular date in mongoose?

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

Answers (1)

Talha Awan
Talha Awan

Reputation: 4619

A part of the document cannot be deleted with ttl. I can think of two other options as a workaround:

  1. Reference

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.

  1. Cronjob/Scheduler

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

Related Questions