Home > Enterprise >  Mongoose - How to change the TTL based on another field?
Mongoose - How to change the TTL based on another field?

Time:02-08

How would I set the TTL based on another field in the schema? I want to set the the expireAt field to whatever value accountType is (the value can be a month / a week / a day).However, this code doesn't expire the document or change the expiry date. I've tried many variations of the TTL field but it doesn't seem to work.

import mongoose from 'mongoose'
import { generateKey } from '../lib/generateKey'

const KeySchema = new mongoose.Schema({
  key: {
    type: String,
    default: generateKey,
    required: true,
  },
  accountType: { /* The value can be a month, a week or a day*/
    type: String,
    required: true,
  },
  dailyLimit: {
    type: Number,
    default: 0,
    required: true,
  },
  expireAt: {
    type: Date,
    default: Date.now,
    index: {
      expireAfterSeconds: 60
    }
  },
})

KeySchema.pre('save', function (next) {
  switch (this.accountType) {
    case 'month':
      this.expireAt.index = {
        expires: 60 * 60 * 24 * 30
      }
      break
    case 'week':
      this.expireAt.index = {
        expires: 60 * 60 * 24 * 7
      }
      break
    case 'day':
      this.expireAt.index = {
        expires: 60 * 60 * 24 * 1
      }
      break
  }

  next()
})

export default mongoose.models.Key || mongoose.model('Key', KeySchema)

I've tried createdAt: { type: Date, expires: 600 }, KeySchema.index({ createdAt: 1 }, { expireAfterSeconds: 3600 }) expireAt: { type: Date, default: Date.now, index: { expires: '5s' }}

CodePudding user response:

MongoDB handles TTL using an index

Mongoose creates the TTL index at the same time it create all of the other indexes, based on the schema, and the same index is used for all documents.

While it is possible to have partial indexes based on field values, MongoDB does not permit creating multiple indexes that contain the same keys but different options, like expiry.

Instead of trying to vary the index option expireAfterSeconds for each document, you might add another field to the scheme named deleteAt with expireAfterSeconds set to 0, then in the pre-save function set deletedAt based on the values of the expireAt and accountType fields.

  •  Tags:  
  • Related