2016-04-19 59 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

相关问题