在mongodb 3.0(.Net驱动程序2.0)中使用TTL未到期的文档

时间:2015-05-30 03:56:47

标签: mongodb mongodb-.net-driver mongodb-csharp-2.0

我有以下代码。 EnsureIndexes由构造函数调用,以确保在_expireAt字段上创建了TTL索引。然后,当通过调用AddOrUpdateItem方法插入文档时,它会将未来日期添加到_expireAt字段。但是,该日期过去了,文档永不过期。我做错了什么?

private void EnsureIndexes()
    {
        if (!_indexChecked)
        {
            // TTL index
            var tsk = 
                MongoCollection.Indexes.CreateOneAsync(Builders<BsonDocument>.IndexKeys.Ascending("_expireAt"),
                        new CreateIndexOptions() { ExpireAfter = TimeSpan.FromSeconds(0) });

            tsk.Wait();

            _indexChecked = true;
        }
    }
public void AddOrUpdateItem(string key, TValue value, TimeSpan timeout)
    {
        var json = value.ToJson();
        dynamic jObject = JObject.Parse(json);
        jObject._expireAt = DateTime.UtcNow.Add(timeout);
        json = jObject.ToString();

        var replacementDocument = BsonSerializer.Deserialize<BsonDocument>(json);
        var filter = new BsonDocument("_id", key);
        var options = new UpdateOptions {IsUpsert = true};
        var tsk = MongoCollection.ReplaceOneAsync(filter, replacementDocument, options);

        try
        {
            tsk.Wait();
        }
        catch (AggregateException ex)
        {
            // TODO: Log

            throw;
        }
    }

使用Mongo集合上的getIndices命令返回以下内容。

> db.Users.getIndices()

[         {                 “v”:1,                 “关键”:{                         “_id”:1                 },                 “name”:“ id ”,                 “ns”:“AuditDemo.Users”         },         {                 “v”:1,                 “关键”:{                         “_expireAt”:1                 },                 “name”:“_ expireAt_1”,                 “ns”:“AuditDemo.Users”,                 “expireAfterSeconds”:0         } ] &GT;

在我的AddOrUpdateItem方法中,我首先将泛型类型序列化为json,以便能够为expireAt添加动态元素。然后我使用BsonSerializer将这个修改过的json反序列化为BsonDocument。此时,BsonDocument是否将datetime json字符串转换为BSon日期类型以使TTL索引起作用?

findOne命令的结果

> db.Users.findOne({"_expireAt":{$exists: true}})

{         “_id”:“0”,         “UserGuid”:{                 “价值”:“054f6141-e655-41dd-a9d5-39382d3360ab”         },         “UserName”:null,         “名字” : {                 “价值”:“约旦”         },         “姓” : {                 “价值”:“ACEVEDO”         },         “电子邮件”:{                 “价值”:“JORDAN.ACEVEDO@fake.com”         },         “__typ”:“AuditDemo.ConsoleApplication.Models.Wss.UserInfo,ConsoleTest App,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null“,         “_expireAt”:“2015-05-31T10:23:15.8979321Z” } &GT;

1 个答案:

答案 0 :(得分:0)

好的,我想出了如何纠正这个日期问题。我从JSON.Net获得的日期时间字符串未被存储为BSON日期对象。所以我不得不在反序列化的BsonDocument属性上调用BsonDateTime.create()方法并强制它成为BSON日期。当它以正确的数据类型存储时,TTL索引按预期工作。

        DateTime expiresDate = new DateTime(DateTime.UtcNow.Ticks, DateTimeKind.Utc).Add(timeout);
        var replacementDocument = BsonSerializer.Deserialize<BsonDocument>(json);
        replacementDocument["_expireAt"] = BsonDateTime.Create(expiresDate);
        var filter = new BsonDocument("_id", key);
        var options = new UpdateOptions {IsUpsert = true};
        var tsk = MongoCollection.ReplaceOneAsync(filter, replacementDocument, options);