C# Driver TTL at specific time

Hi,

Me and my friend Google have for hours now looked into TTL. I am searching for a way to have individual documents to be be removed on their own specific ExpireAt.

I have read this https://docs.mongodb.com/manual/tutorial/expire-data/#expire-documents-at-a-specific-clock-time and I can’t seem to find any examples that for me work.

I create my index like this if index not exist:

var indexModel = new CreateIndexModel<MyEntity>(
keys: Builders<MyEntity>.IndexKeys.Ascending("ExpireAt"),
options: new CreateIndexOptions
{
  ExpireAfter = TimeSpan.FromSeconds(0),
  Name = "ExpireAtIndex"
});

_collection.Indexes.CreateOne(indexModel);

Setting it to zero seems to be the correct way if I haven’t totally misunderstood something?

Document modell MyEntity (dates are in UTC):

public class MyEntity
{
  [BsonId]
  public ObjectId Id { get; set; }

  [BsonElement]
  public string TestProp { get; set; }

  [BsonElement]
  public DateTime ServiceDate { get; set; } // this is the value the index should consider

  [BsonElement]
  public DateTime CreatedAt { get; set; }

  [BsonElement()]
  public DateTime ExpireAt { get; set; } // ServiceDate + adding 120 seconds 
}

I see the index being created in MongoDB Compass Client and a document being created when I insert one.

var entity = new MyEntity()
{
  ServiceDate = servicedate,
  TestProp = testprop,
  CreatedAt = createdAt,
  ExpireAt = serviceDate.AddSeconds(120)
};

var updateResult = await _collection.ReplaceOneAsync(
  f => f.TestProp == entity.TestProp,
  entity,
  new ReplaceOptions { IsUpsert = true });

What happens in the Compass client is that the inserted document is removed way before 120 seconds. Could someone please share some light or put me in the right direction on how to achieve so I can have the behaviour that a document is removed 120 seconds after its actual ServiceDate? Or have I misunderstood TTL altogether?

//Daniel

Hi @Daniel_Svensson,

What happens in the Compass client is that the inserted document is removed way before 120 seconds. Could someone please share some light or put me in the right direction on how to achieve so I can have the behaviour that a document is removed 120 seconds after its actual ServiceDate? Or have I misunderstood TTL altogether?

When you set the expireAfterSeconds value to 0 (via ExpireAt) the TTL Index will remove documents at the_exact time_ specified by the indexed value.

var entity = new MyEntity()
{
  ServiceDate = servicedate,
  TestProp = testprop,
  CreatedAt = createdAt,
  ExpireAt = serviceDate.AddSeconds(120)
};

Given the example above, if ExpireAt is a date/time in the past, and adding 120 seconds to that timestamp would still be in the past, when the TTL background thread runs (every 60 seconds by default) ALL documents that match this criteria will be deleted.

I would start by reviewing the date/time of ExpireAt for these documents and comparing them to the current date/time to ensure the values are actually in the future; not in the past.