在golang中使用mongo,在指定的秒数后使文档过期?

Using mongo in golang, Expire Documents after a Specified Number of Seconds?

我正在尝试使用 mongo-go-driver 进行一些简单的操作。 我在一个集合中插入了一些数据,我希望它们在几秒后自动删除。

我已阅读以下文档:https://docs.mongodb.com/manual/tutorial/expire-data/#expire-documents-after-a-specified-number-of-seconds

然后我在GO里写了一些东西,但是好像没有达到我预期的效果。可能有什么地方我没有得到,或者我做错了。

package main

import (
    "bytes"
    "context"
    "fmt"
    "log"
    "text/tabwriter"
    "time"

    "github.com/Pallinder/go-randomdata"
    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/bson/primitive"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

func main() {
    ctx := context.TODO()

    client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017"))
    if err != nil {
        log.Fatal(err)
    }
    err = client.Connect(ctx)
    if err != nil {
        log.Fatal(err)
    }

    db := client.Database("LADB")
    col := db.Collection("LACOLL")

    // add index to col
    // the goal is to set a TTL for datas to only 1 secondes (test purpose)
    model := mongo.IndexModel{
        Keys:    bson.M{"createdAt": 1},
        Options: options.Index().SetExpireAfterSeconds(1),
    }
    ind, err := col.Indexes().CreateOne(ctx, model)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(ind)

    // insert some datas each seconds
    for i := 0; i < 5; i++ {
        name := randomdata.SillyName()
        res, err := col.InsertOne(ctx, NFT{Timestamp: time.Now(), CreatedAt: time.Now(), Name: name})
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println("Inserted", name, "with id", res.InsertedID)
        time.Sleep(1 * time.Second)
    }

    // display all
    cursor, err := col.Find(ctx, bson.M{}, nil)
    if err != nil {
        log.Fatal(err)
    }
    var datas []NFT
    if err = cursor.All(ctx, &datas); err != nil {
        log.Fatal(err)
    }

    // I expect some datas not to be there (less than 5)
    fmt.Println(datas)
}

type NFT struct {
    ID        primitive.ObjectID `bson:"_id,omitempty"`
    CreatedAt time.Time          `bson:"createdAt,omitempty"`
    Timestamp time.Time          `bson:"timestamp,omitempty"`
    Name      string             `bson:"name,omitempty"`
}

您的示例没有任何问题,它有效。

请注意,您指定的expireAfterSeconds是文档过期createdAt后的持续时间,该时刻是文档可能被删除的最早时间,但不保证删除将“立即”发生,恰好在那个时候。

引用自MongoDB docs: TTL indexes: Timing of the Delete Operation:

The TTL index does not guarantee that expired data will be deleted immediately upon expiration. There may be a delay between the time a document expires and the time that MongoDB removes the document from the database.

The background task that removes expired documents runs every 60 seconds. As a result, documents may remain in a collection during the period between the expiration of the document and the running of the background task.

Because the duration of the removal operation depends on the workload of your mongod instance, expired data may exist for some time beyond the 60 second period between runs of the background task.

如您所见,如果文档过期,最坏情况下后台任务可能需要 60 秒才能启动并开始删除过期文档,并且如果有很多(或数据库负载过重) , 删除所有过期文档可能需要一些时间。