MGO TTL索引创建以有选择地删除文档

时间:2016-04-19 14:00:52

标签: mongodb go mgo ttl mongodb-indexes

我正在使用Golang和MongoDB。我有一个集合需要保存一个持久性或易变的文档。因此,如果它设置了一个过期日期(如示例expireAt),则该文档被视为易失性并被删除,否则它将保留在集合中,除非它将被手动删除。

阅读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设置为有效日期,否则我将把它留给Go time.Time零值。

这是我的代码库

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可以将zerovalue解释为无效日期是有效的吗?

从文档中January 1, year 1, 00:00:00.000000000 UTC实际上似乎是一个有效的日期..

到目前为止,我一直在想这样做:

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

1 个答案:

答案 0 :(得分:3)

  

如果expireAt键有效,如何设置索引以便删除文档?

使用mgo.v2设置TTL索引的示例如下:

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

上述示例设置为120秒到期。另见Expire Data from Collections by Setting TTL

  

是否仍然可以使某些文件完全没有过期?由于这是我期待获得一个集合的行为,其中一些文档到期而其他文档仍然持久

您可以为omitempty struct field指定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)

稍后,您可以使用Update()设置expireAt字段,例如:

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

expireAt字段设置有效时间值会使其符合TTL索引的条件。即不再存在。

根据您的使用情况,您也可以Remove()文档,而不是更新和依赖TTL索引。