1

I need a solution to delete the documents from a table in mongo DB after certain time automatically. I have some bugs in this code. even if I specify the time to expire is 2 minutes, it deletes document earlier than 2 minutes.

My code:

var mongoose = require("mongoose");

var loginSchema = new mongoose.Schema(
  /*{
    expire_at: { type: Date, default: Date.now, expires: 60 }
  },*/
  {
    email: {
      type: String,
      require: true,
      min: 6,
      max: 255,
      match: /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/
    },
    password: {
      type: String,
      require: true,
      max: 1024,
      min: 6
    },
    latitude: {
      type: String,
      require: true
    },
    longitude: {
      type: String,
      require: true
    },
    IPAddress: {
      type: String,
      require: true
    },
    ISP: {
      type: String,
      require: true
    },
    Location: {
      type: String,
      require: true
    },
    isMobile: {
      type: Boolean
    },
    MobileDeviceID: {
      type: String
    },
    date: {
      type: Date,
      default: Date.now
    },
    expireAt: { 
      type: Date, 
      default: Date.now,
      index: { expires: '2m' }
    }
  }
);

module.exports = mongoose.model("Login", loginSchema);
James Z
  • 12,209
  • 10
  • 24
  • 44

3 Answers3

4

You can use Time to live (TTL) Indexes that is provided by MongoDB out of the box. It automatically expires the data after TTL passes and then deletes them from the collection according to MongoDB Docs

TTL indexes are special single-field indexes that MongoDB can use to automatically remove documents from a collection after a certain amount of time or at a specific clock time. Data expiration is useful for certain types of information like machine generated event data, logs, and session information that only need to persist in a database for a finite amount of time.

So you need to create a TTL index like this

loginSchema.createIndex({"expire_at": 1 }, { expireAfterSeconds: 5 });

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.

Hope this helps

Hadi Mir
  • 4,497
  • 2
  • 29
  • 31
1

As far as I have read from various sources searching for the same problem, Mongodb does not delete the document immediately at the time specified in the field, it can postpone the task based upon the workload of the server at any point of time. Also based upon how it reacts on time events. That is why it deletes the document some more time after the time specified has elapsed.(Not sure why it is preponing the task, maybe you can re-check that).

Also using schema.createIndex() method as specified above in the answer also leads to the same scenerio. Found No advantage in using that method too.

Aman Chawla
  • 710
  • 6
  • 8
0

Deleting a document from a collection can also be done using a post hook on save event of a document. Use setTimeout function to perform the task automaticaaly after the desired time has passed.

schema.post('save', function(doc, next) {
  setTimeout(function() {
    console.log("fire on passing desired time after saving document");
    // function to delete the document here
  }, 10000);
});

this will fire after 10 seconds after the document has been saved. you can change the time argument and enter the function to delete the desire document

Aman Chawla
  • 710
  • 6
  • 8
  • really?? What if thousands of user at the site do this task somehow, then won't you be overloading and crashing your server with too many requests?? Making it super-slow –  May 20 '22 at 20:58