Update TTL Indexed Field expiry date later

Hi,
I am trying to implement Mongodb TTL feature into my project. Here I have one scenario, i need to update ttl field date value later.
In this case, I insert record with “expiryAt = null”, but later i will update date on “expiryAt” variable for expire this record by updating.
Above case looks not working.
Please assist me on this, what should i do for this above case?

Hi @Visva_Ram,

Welcome to MongoDB community!

Its possible to do that via collMod command:

https://docs.mongodb.com/manual/reference/command/collMod/#change-expiration-value-for-indexes

In this command you will need to specify the collection, the index and the new expireAfterSeconds expression.

db.runCommand({
   collMod: "user_log",
   index: {
      keyPattern: { lastAccess: 1 },
      expireAfterSeconds: 3600
   }
})

Thanks
Pavel

Thanks Much Pavel.

In my case expireAfterSeconds is always zero in index. I am trying to control this by having date attribute from the document.

@Visva_Ram

I think I understand what you are attempting to achieve. As you may already know the expireAfterSeconds should be 0 to use the timestamp as the expiry time.

I have just recreated what I think you are doing below and it works fine. The field you are using for TTL must be a date type or array of date values.

There is no real point in using a field with null, I would recommend just not inserting with that field, and add it when you do the update.

ttl index
rs0:PRIMARY> db.deleteme.createIndex({expireAt:1},{expireAfterSeconds:0})
{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 1,
	"numIndexesAfter" : 2,
	"commitQuorum" : "votingMembers",
	"ok" : 1,
	"$clusterTime" : {
		"clusterTime" : Timestamp(1608036401, 1),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	},
	"operationTime" : Timestamp(1608036401, 1)
}
Insert some documents
rs0:PRIMARY> ISODate()
ISODate("2020-12-15T12:53:50.780Z")
rs0:PRIMARY> db.deleteme.insertMany(
  [ 
    {_id:1,expireAt:ISODate("2020-12-15T12:59")}, 
    {_id:2,expireAt:null},
    {_id:3,expireAt:ISODate("2020-12-15T12:58")}
  ]
)
{ "acknowledged" : true, "insertedIds" : [ 1, 2, 3 ] }
rs0:PRIMARY> db.deleteme.find()
{ "_id" : 1, "expireAt" : ISODate("2020-12-15T12:59:00Z") }
{ "_id" : 2, "expireAt" : null }
{ "_id" : 3, "expireAt" : ISODate("2020-12-15T12:58:00Z") }

Wait…

Check removal
rs0:PRIMARY> ISODate()
ISODate("2020-12-15T12:59:54.106Z")
rs0:PRIMARY> db.deleteme.find()
{ "_id" : 2, "expireAt" : null }
Update document with null value to an ISODate
rs0:PRIMARY> db.deleteme.update({_id:2},{expireAt:ISODate('2020-12-15T13:03')})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
rs0:PRIMARY> db.deleteme.find()
{ "_id" : 2, "expireAt" : ISODate("2020-12-15T13:03:00Z") }

Wait…

Check Removal
rs0:PRIMARY> ISODate()
ISODate("2020-12-15T13:03:44.895Z")
rs0:PRIMARY> db.deleteme.find()

Profit!

1 Like

Thanks Much Chris

Yes, It is working fine for me.

One problem i am facing with indexing field for TTL from Java which we are using Spring Data Mongodb Framework.

In that below case for nested object spring data mongodb creating multiple TTL index for Class(ClassA). So finally multiple TTL index there in mongodb.

  1. What will happen when there is multiple TTL index for different field for the same collection.
  2. How to annotate this ttl index from actual class (ClassA) by having the variable in abstract?.
    Note : Compound index i am doing from actual class (Class A), that will not affect even having this class instance in other db class.

Nested Object by extending abstract:

@Document
@CompoundIndexes({
@CompoundIndex(name = “var1_IX”, def = “{‘classBVar.var1’: 1}”),
}
public class ClassA extends MyDBObjectAbstract {
private ClassB classBVar = new ClassB() ;
}

Noraml Object by extending abstract :

@Document
@CompoundIndexes({
@CompoundIndex(name = “var1_InnerIX”, def = “{‘var1’: 1}”),
}
public class ClassB extends MyDBObjectAbstract {
private String var1 =“Welcome”
}

Abstract class with TTL Index Annotation :

public abstract class FMObjectAbstract {
@Indexed(name = “expireRecordAt_index”, expireAfterSeconds = 0)
private Date expireRecordAt=null;
}

Multiple Index created for Class A for TTL:

{
“v” : 2,
“key” : {
“classBVar.expireRecordAt” : 1
},
“name” : “classBVar.expireRecordAt_index”,
“ns” : “MYDB.ClassA”,
“expireAfterSeconds” : NumberLong(0)
},
{
“v” : 2,
“key” : {
“expireRecordAt” : 1
},
“name” : “expireRecordAt_index”,
“ns” : “MYDB.ClassA”,
“expireAfterSeconds” : NumberLong(0)
}