Expiration date for items in a collection


#1

i started learning meteor a while ago and went on to begin with my first project which is a server for a certain board game.
i have started with a main chat room, and decided to keep all the messages in a collection. now, i do not want the old messages to be saved for ever, but only for a few hours, say 3 hours. is there a simple way to tell a collection to only store items for 3 hours and then delete them? or mabye there is a way to tell a collection to only store a certain amount of items and then start deleting the last ones when new items are inserted?

thanks in advance!


#2

has a good example of how to do this. Note that it uses _ensureIndex which is a mongo command, but has the underscore because it’s not part of the official Meteor API. This means it could change in the future.


#3

https://docs.mongodb.org/manual/tutorial/expire-data/
Standart mongodb TTL


#4

Thank you both, it seems that simply writing :
db.messages.createIndex( { “createdAt”: 1 }, { expireAfterSeconds: 10 } );
on cmd made it work.
i wonder now, is there a way to use db commands through the code instead of cmd? cause like this i am afraid stuff might reset some day and ill have to write all the commands all over again. i tried writing the same line on the server code and it did not recognize “db” (probably a noob attempt by me).


#5

Inside of Meteor you would typically do this in a server/ file:

Meteor.startup(function() {
  SomeCollection._ensureIndex( { "createdAt": 1 }, { expireAfterSeconds: 10 } );
});

Edited for documented approach:

Meteor provides the rawCollection method to gain access to the underlying NPM MongoDB driver. So, the following is probably the approach you should take to avoid deprecation of _ensureIndex:

Meteor.startup(function() {
  SomeCollection.rawCollection().ensureIndex( { "createdAt": 1 }, { expireAfterSeconds: 10 } );
});

#6

thank you for your answer.
the first option you gave worked like a charm, however the second one (with rawCollection) threw me an error:
Error: Cannot use a writeConcern without a provided callback.


#7

My bad - I usually use the first form. However, to the point: ensureIndex requires a callback, so you would probably begin by wrapping it in a Meteor.wrapAsync, to allow it to be used in a linear way:

Meteor.startup(function() {
  const rawCollection = SomeCollection.rawCollection();
  const ensureIndex = Meteor.wrapAsync(rawCollection.ensureIndex, rawCollection);
  ensureIndex({ createdAt: 1 }, { expireAfterSeconds: 10 });
});


#8

Thanks @robfallows for this info, it helped me out.

Just want to add… if like me, you set the expiration time to 10 seconds to see if it works, and then you want to set it to 1 day, you can’t just change the value and restart. The index is already set. Instead you have to use collMod in the mongo shell.

db.runCommand( {"collMod" :  "mycollection" , "index" : { "keyPattern" : {"createdAt" : 1} , "expireAfterSeconds" : 3600*24 } } );