2015-05-30 64 views
0

我有以下代碼。 EnsureIndexes由構造函數調用,以確保在_expireAt字段上創建了TTL索引。然後,通過調用AddOrUpdateItem方法插入文檔時,它會將未來日期添加到_expireAt字段。但是,該日期過去了,文件永不過期。我究竟做錯了什麼?在mongodb 3.0(.Net驅動程序2.0)中使用TTL不過期的文檔

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 }, 「名稱」: 「ID」, 「NS」:「AuditDemo 。用戶」 },{ 「v」:1, 「鍵」:{ 「_expireAt」:1 }, 「名稱」: 「_expireAt_1」, 「NS」: 「AuditDemo.Users」, 「expireAfterSeconds」:0 } ] >

以我AddOrUpdateItem方法我第一序列的通用類型,以便能夠添加一個動態元素的expireAt到JSON。然後我使用BsonSerializer將這個修改後的json反序列化爲BsonDocument。此時,BsonDocument是否將日期時間json字符串轉換爲BSon日期類型以便TTL索引正常工作? 「0」, 「UserGuid」:{ 「值」:從findOne命令

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

{ 「_id」

結果 「054f6141-e655-41dd-a9d5-39382d3360ab」 } , 「用戶名」:空, 「名字」:{ 「值」: 「JORDAN」 }, 「名字」:{ 「值」: 「ACEVEDO」 }, 「電子郵件」:{ 「Value」:「[email protected]」 }, 「__typ」:「AuditDemo.ConsoleApplication.Models.Wss.UserInfo,ConsoleTest App,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null 」 「_expireAt」: 「2015-05-31T10:23:15.8979321Z」 } >

+0

請使用編輯按鈕將'db.YourCollection.getIndices()'的輸出添加到您的問題中。 –

+0

@ MarkusWMahlberg:我更新了原來的帖子,其中調用getIndices的結果。該指數確實存在。但我懷疑這裏可能發生的是將json文檔反序列化爲bson,BsonSerializer可能不會將json日期字符串轉換爲Bson日期數據類型。如果是這樣的話,那麼如何存儲過期的json文檔。 – Arif

+0

恩,我們來檢查一下。請添加'db.Users.findOne({「_ expireAt」:{$ exists:true}})' –

回答

0

OK,我想通了,如何解決這個問題迄今。我從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); 
相關問題