2016-04-19 98 views
2

我正在使用Golang和MongoDB。我有一個需要保存可以持久或不穩定的文檔的集合。因此,如果它設置了過期日期(如示例expireAt),則該文檔被認爲是易失性的並且被刪除,否則它將被保存在集合中,除非它被手動刪除。MGO TTL索引創建有選擇地刪除文檔

閱讀this doc我發現了一個可能工作的索引,因爲我需要它。

基本上我需要複製這種指標中的MgO:

db.log_events.createIndex({ "expireAt": 1 }, { expireAfterSeconds: 0 }) 

db.log_events.insert({ 
    "expireAt": new Date('July 22, 2013 14:00:00'), 
    "logEvent": 2, 
    "logMessage": "Success!" 
}) 

我讀過(我在尋找回來的這些信息的來源),如果expireAt不是有效日期刪除將不會觸發。因此,我認爲我需要做的就是在需要時將expireDate設置爲有效日期,否則我會將其保留爲零值。

這是我的代碼庫

type Filter struct { 
    Timestamp time.Time  `bson:"createdAt"` 
    ExpireAt time.Time  `bson:"expireAt"` 
    Body  string  `bson:"body"` 
} 

// Create filter from data received via REST API. 
var filter Filter 
timestamp := time.Now() 

if theUserAction == "share" { // This is action will set the document as volatile 
    filter.ExpireAt = time.Now().Add(24 * time.Hour * 14) 
} 

filter.Timestamp = timestamp 
filter.Body = "A BODY" 

// Store filter in database 
session, err := mdb.GetMgoSession() // This is a wrapping method that returns a valid mgo session 
if err != nil { 
    return NewErrorInternal("Error connecting to database", err) 
} 
defer session.Close() 


// Get db with global data for legent 
collection := session.DB(database).C(filtersCollection) 

我的問題是:我怎麼能設置索引因此,如果expireAt關鍵是有效的,它會刪除該文件? 讀mgo documentation about Index Type它似乎並不像有一種方法來複制先前所述的指數,因爲庫只提供了ExpireAfter場..

而且,它是有效的假設一個零值可以通過MongoDB的作爲被解釋失效日期?

從它January 1, year 1, 00:00:00.000000000 UTC這實際上似乎是一個有效的日期的文檔..

什麼我想過到目前爲止在做這樣的事情:

filtIdx := mgo.Index{ 
    Key:  []string{"expireAt"}, 
    Unique:  false, 
    Background: true, 
    Sparse:  false, 
    ExpireAfter: 0, 
} 
+0

我可能是錯的,但我的頭頂我認爲'expireAfterSeconds:0'實際上會被忽略,並且'0'值無論如何,因爲我「相信」它需要是一個正值。無論如何,TTL清理過程至多每分鐘運行一次,因此任何小於60秒的過期將至少持續一分鐘。至於其他方面,我並不是說你「不能」這樣做,但你可能想重新考慮在Go代碼中定義索引的效用。索引只需定義一次,因此最好在「部署腳本」中實現,而不是通用代碼的一部分。 –

+0

當您希望索引在另一個日期鍵上過期時,文檔本身指定tu使用'expireAfterSeconds:0'。關於索引創建的地方,是的,你說得對,它現在實際上是在部署腳本中。 – FredMaggiowski

+0

你爲什麼會認爲你在通知我有關文檔的一些事情?這不是它所說的,您可以使用的「唯一」鍵是索引中指定的「單數」數據。而「那個」正是文檔所說的。老實說,每條評論都有鏈接到用戶配置文件。如果你花一點時間看,那麼你可能會明白,你想「告知」的人比你有更好的概念,因此「給你一些好的建議」。 –

回答

2

我如何設置索引,因此如果expireAt鍵有效,它將刪除文檔?

一個例子來設置使用mgo.v2是如下一個TTL索引:其中,上面的例子中設置爲期滿120秒

index := mgo.Index{ 
    Key:   []string{"expireAt"}, 
    ExpireAfter: time.Second * 120, 
} 
err = coll.EnsureIndex(index) 

。另見Expire Data from Collections by Setting TTL

是否仍然有可能讓某些文件根本沒有到期?由於這是我期待着獲得一個集合,其中一些文件會過期,而其他仍然持續

行爲可以指定omitempty標誌如下ExpireAt結構域:

type Filter struct { 
    Timestamp time.Time `bson:"createdAt"` 
    Body  string `bson:"body"` 
    ExpireAt time.Time `bson:"expireAt,omitempty"` 
} 

基本上如果未設置爲零值,則只包含該字段。查看更多信息mgo.v2 bson.Marshal

現在,例如,您可以插入兩個文檔,其中一個會過期,另一個持續存在。代碼示例:

var foo Filter 
foo.Timestamp = timestamp 
foo.Body = "Will be deleted per TTL index" 
foo.ExpireAt = time.Now() 
collection.Insert(foo) 

var bar Filter 
bar.Timestamp = timestamp 
bar.Body = "Persists until expireAt value is set" 
collection.Insert(bar) 

之後,你可以設置expireAt場與Update(),作爲一個例子:

newValue := bson.M{"$set": bson.M{"expireAt": time.Now()}} 
err = collection.Update(queryFilter, newValue) 

expireAt字段設置有效時間值,將使它有資格參加TTL指數。即不再存在。

根據您的使用情況,或者您也可以使用Remove()文件而不是更新並依賴TTL索引。

+0

謝謝@Wan的回答,它已經過了一年多了,因爲我有這個問題,所以現在我不能測試它以驗證解決方案;無論如何,它似乎是完美的。我沒有關於GOB的'omitempty'關鍵字。問題在於它避免了插入0值的時間,導致該文檔的索引「失效」。我說得對嗎?現在我正在提高答案,我會盡快測試它來接受它! :) – FredMaggiowski

相關問題