Search code examples
c#mongodbmongodb-.net-driver

How to create MongoDB collection with TTL?


I create a collection of objects

public class User
{
public User(string fullname, string email)
{
Fullname = fullname;
Email = email;
}

    public string Fullname { get; }
    public string Email { get; }
}

And create the index and some docs

var collection = _database.GetCollection(“bar”);
collection.Indexes.CreateOne(new CreateIndexModel
(new BsonDocument(“lastModifiedDate”, 1), new CreateIndexOptions { ExpireAfter = new TimeSpan(0, 0, 30) }));

            var user = new User("Vasya", "billgates@ms.com");
            collection.InsertOne(user.ToBsonDocument());
            var user1 = new User("Petya", "Petya@ms.com");
            collection.InsertOne(user1.ToBsonDocument());
            var user2 = new User("Kolya", "Kolya@ms.com");
            collection.InsertOne(user2.ToBsonDocument());
            count = collection.CountDocuments(new BsonDocument());

But when I see http://localhost:8081/db/dbtest/ then I do not see any TTL and documents do not expire after 30 secs.

What I do wrong? How to create collection or documents in it with TTL?


Solution

  • Your user object doesn't have the field you specified on the index

    public class User
    {
        public User(string fullname, string email, DateTime lastModifiedDate) 
        {
            Fullname = fullname;
            Email = email;
            LastModifiedDate = lastModifiedDate;
        }
    
        public string Fullname { get; }
        public string Email { get; }
        public DateTime LastModifiedDate { get; }
    }
    

    Also, the default convention for serialization in MongoDB C# Driver is not camel case so you'll need to update your index to the following:

    var collection = _database.GetCollection("bar");
    collection.Indexes.CreateOne(new CreateIndexModel
    (new BsonDocument("LastModifiedDate", 1), new CreateIndexOptions { ExpireAfter = new TimeSpan(0, 0, 30) }));
    
    

    You might also want to embrace the type safety that C# and the MongoDB Driver gives you by using your User type instead of the BsonDocument. Below is an example of how to do this.

    using MongoDB.Driver;
    
    var client = new MongoClient();
    var database = client.GetDatabase("test");
    var collection = database.GetCollection<User>("users");
    await collection.Indexes.CreateOneAsync(
        Builders<User>.IndexKeys.Ascending(x => x.LastModifiedDate),
        new CreateIndexOptions { ExpireAfter = new TimeSpan(0, 0, 30) });
    
    var user = new User("Vasya", "billgates@ms.com", DateTime.UtcNow);
    collection.InsertOne(user);
    var user1 = new User("Petya", "Petya@ms.com", DateTime.UtcNow);
    collection.InsertOne(user1);
    var user2 = new User("Kolya", "Kolya@ms.com", DateTime.UtcNow);
    collection.InsertOne(user2);
    
    for (var i = 0; i < 10; i++)
    {
        var count = await collection.CountDocumentsAsync(Builders<User>.Filter.Empty);
        Console.WriteLine($"Count: {count} @ {DateTime.UtcNow}");
        await Task.Delay(10000);
    }
    
    
    // Count: 4 @ 02/01/2022 11:42:13
    // Count: 4 @ 02/01/2022 11:42:23
    // Count: 4 @ 02/01/2022 11:42:33
    // Count: 4 @ 02/01/2022 11:42:43
    // Count: 4 @ 02/01/2022 11:42:53
    // Count: 1 @ 02/01/2022 11:43:03
    // Count: 1 @ 02/01/2022 11:43:13
    // Count: 1 @ 02/01/2022 11:43:23
    // Count: 1 @ 02/01/2022 11:43:33
    // Count: 0 @ 02/01/2022 11:43:43
    
    
    public class User
    {
        public User(string fullname, string email, DateTime lastModifiedDate)
        {
            Fullname = fullname;
            Email = email;
            LastModifiedDate = lastModifiedDate;
        }
    
        public string Fullname { get; }
        public string Email { get; }
        public DateTime LastModifiedDate { get; }
    }
    
    

    You might notice that the documents don't get deleted at once but as said in the MongoDB docs

    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. https://docs.mongodb.com/manual/core/index-ttl/#timing-of-the-delete-operation