开发者

Go Mongox轻松实现MongoDB的时间字段自动填充

目录
  • 前言
  • 时间字段填充规则
  • Mongox 的安装
  • 使用 Mongox 进行插入操作
  • 使用 Mongox 进行更新操作
    • 更新操作
    • Upsert 操作
  • 小结

    前言

    MongoDB 的集合中,时间字段(如 创建时间更新时间)通常是必不可少的。在使用 Go 语言操作 MongoDB 时,例如执行插入或更新操作,我们需要手动设置这些时间字段的值。然而,每次手动赋值不仅繁琐,还容易导致代码重复。那么,是否可以在程序层面实现自动填充呢?目前,官方的 mongo-go-driver 并不支持自动填充时间字段,而 mongox 库提供了这一能力。本文将介绍如何使用 mongox 库,在插入和更新数据时自动填充时间字段,从而提升开发效率并减少重复代码。

    Go Mongox轻松实现MongoDB的时间字段自动填充

    时间字段填充规则

    在定义结构体时,如果字段符合以下特性,则可以被自动填充:

    字段名称和类型符合规定

    结构体字段名为 CreatedAtUpdatedAt 字段,且类型为 time.Timeint/int64。当为 int/int64 时,将会填充当前时间戳秒数。

    字段包含特定标签

    • mongox:"autoCreateTime":在插入文档时,如果该字段的值为零值,则会自动设置为当前时间。除了 time.Time 类型,你还可以使用 secondmillinano 三种时间戳精度,使用样例:mongox:"autoCreateTime:milli" 如果不指定 milli,默认是 second
    • mongox:"autoUpdateTime":在插入文档时,如果该字段的值为零值或更新文档时,会自动设置为当前时间。除了 time.Time 类型,你还可以使用 secondmillinano 三种时间戳精度。使用样例:mongox:"autoUpdateTime:milli" 如果不指定 milli,默认是 second

    Mongox 的安装

    通过以下命令安装 mongox 库:

    go get github.com/chenmingyong0423/go-mongox/v2
    

    使用 Mongox 进行插入操作

    结构体定义

    type User struct {
        ID        bson.ObjectID `bson:"_id,omitempty" mongox:"autoID"`
        Name      string        `bson:"name"`
        Age       int           `bson:"age"`
        CreatedAt time.Time     `bson:"created_at"`
        UpdatedAt int           `bson:"updated_at"` // 使用秒级时间戳填充字段
    
        CreateSecondTime int64 `bson:"create_second_time" mongox:"autoCreateTime"`        // 使用秒级时间戳填充字段
        UpdateSecondTime int64 `bson:"update_second_time" mongox:"autoUpdateTime:second"` // 使用秒级时间戳填充字段
        CreateMilliTime  int64 `bson:"create_milli_time" mongox:"autoCreateTime:milli"`   // 使用毫秒级时间戳填充字段
        UpdateMilliTime  int64 `bson:"update_milli_time" mongox:"autoUpdateTime:milli"`   // 使用毫秒级时间戳填充字段
        CreateNanoTime   int64 `bson:"create_nano_time" mongox:"autoCreateTime:nano"`     // 使用纳秒级时间戳填充字段
        UpdateNanoTime   int64 `bson:"update_nano_time" mongox:"autoUpdateTime:nano"`     // 使用纳秒级时间戳填充字段
    }
    

    示例代码

    package main
    
    import (
        "context"
        "fmt"
        "time"
    
        "go.mongodb.org/mongo-driver/v2/bson"
    
        "go.mongodb.org/mongo-driver/v2/mongo"
        "go.mongodb.org/mongo-driver/v2/mongo/options"
        "go.mongodb.org/mongo-driver/v2/mongo/readpref"
    
        "github.com/chenmingyong0423/go-mongox/v2"
    )
    
    type User struct {
        ID        bson.ObjectID `bson:"_id,omitempty" mongox:"autoID"`
        Name      string        `bson:"name"`
        Age       int           `bson:"age"`
        CreatedAt time.Time     `bson:"created_at"`
        UpdatedAt int           `bson:"updated_at"` // 使用秒级时间戳填充字段
    
        CreateSecondTime int64 `bson:"create_second_time" mongox:"autoCreateTime"`        // 使用秒级时间戳填充字段
        UpdateSecondTime int64 `bson:"update_second_time" mongox:"autoUpdateTime:second"` // 使用秒级时间戳填充字段
        CreateMilliTime  int64 `bson:"create_milli_time" mongox:"autoCreateTime:milli"`   // 使用毫秒级时间戳填充字段
        UpdateMilliTime  int64 `bson:"update_milli_time" mongox:"autoUpdateTime:milli"`   // 使用毫秒级时间戳填充字段
        CreateNanoTime   int64 `bson:"create_nano_time" mongox:"autoCreateTime:nano"`     // 使用纳秒级时间戳填充字段
        UpdateNanoTime   int64 `bson:"update_nano_time" mongox:"autoUpdateTime:nano"`     // 使用纳秒级时间戳填充字段
    }
    
    func main() {
        mongoClient, err := newMongoClient()
        if err != nil {
            panic(err)
        }
        client := mongox.NewClient(mongoClient, &mongox.Config{})
        database := client.NewDatabase("db-test")
    
        userColl := mongox.NewCollection[User](database, "users")
    
        user := &User{
            Name: "陈明勇",
            Age:  18,
        }
        _, err = userColl.Creator().InsertOne(context.Background(), user)
        if err != nil {
            panic(err)
        }
        fmt.Println(!user.CreatedAt.IsZero())   // true
        fmt.Println(user.UpdatedAt != 0)        // true
        fmt.Println(user.CreateSecondTime != 0) // true
        fmt.Println(user.UpdateSecondTime != 0) // true
        fmt.Println(user.CreateMilliTime != 0)  // true
        fmt.Println(user.UpdateMilliTime != 0)  // true
        fmt.Println(user.CreateNanoTime != 0)   // true
        fmt.Println(user.UpdateNanoTime != 0)   // true
    }
    
    // 示例代码,仅供参考
    func newMongoClient() (*mongo.Client, error) {
        client, err := mongo.Connect(options.Client().ApplyURI("mongodb://localhost:27017").SetAuth(options.Credential{
            Username:   "test",
            Password:   "test",
            AuthSource: "db-test",
        }))
        if err != nil {
            return nil, err
        }
        err = client.Ping(context.Background(), readpref.Primary())
        if err != nil {
            panic(err)
        }
        return client, nil
    }

    插入数据后,通过零值比较判断字段值是否被填充。fmt.Println 语句都输出 true,说明所有时间字段的值都被填充。

    使用 Mongox 进行更新操作

    更新操作

    package main
    
    import (
        "context"
        "fmt"
        "time"
    
        "github.com/chenmingyong0423/go-mongox/v2/builder/query"
        "github.com/chenmingyong0423/go-mongox/v2/builder/update"
    
        "go.mongodb.org/mongo-driver/v2/bson"
    
        "go.mongodb.org/mongo-driver/v2/mongo"
        "go.mongodb.org/mongo-driver/v2/mongo/options"
        "go.mongodb.org/mongo-driver/v2/mongo/readpref"
    
        "github.com/chenmingyong0423/go-mongox/v2"
    )
    
    type User struct {
        ID        bson.ObjectID `bson:"_id,omitempty" mongox:"autoID"`
        Name      string        `bson:"name"`
        Age       int           `bson:"age"`
        CreatedAt time.Time     `bson:"created_at"`
        UpdatedAt int           `bson:"updated_at"` // 使用秒级时间戳填充字段
    
        CreateSecondTime int64 `bson:"create_second_time" mongox:"autoCreateTime"`        // 使用秒级时间戳填充字段
        UpdateSecondTime int64 `bson:"update_second_time" mongox:"autoUpdateTime:second"` // 使用秒级时间戳填充字段
        CreateMilliTime  int64 `bson:"create_milli_time" mongox:"autoCreateTime:milli"`   // 使用毫秒级时间戳填充字段
        UpdateMilliTime  int64 `bson:"update_milli_time" mongox:"autoUpdateTime:milli"`   // 使用毫秒级时间戳填充字段
        CreateNanoTime   int64 `bson:"create_nano_time" mongox:"autoCreateTime:nano"`     // 使用纳秒级时间戳填充字段
        UpdateNanoTime   int64 `bson:"update_nano_time" mongox:"autoUpdateTime:nano"`     // 使用纳秒级时间戳填充字段
    }
    
    func main() {
        mongoClient, err := newMongoClient()
        if err != nil {
            panic(err)
        }
        client := mongox.NewClient(mongoClient, &mongox.Config{})
        database := client.NewDatabase("db-test")
    
        userColl := mongox.NewCollection[User](database, "users")
    
        // 用于比较后面的时间字段是否更新
        now := time.Now()
    
        _, err = userColl.Updater().
            Filter(query.Eq("name", "陈明勇")).
            Updates(update.Set("age", 26)).
            UpdateOne(context.Background())
        if err != nil {
            panic(err)
        }
    
        user, err := userColl.Finder().
            Filter(query.Eq("name", "陈明勇")).
            FindOne(context.Background())
        if err != nil {
            panic(err)
        }
    
        fmt.Println(user.UpdatedAt > int(now.Unix()))   // true
        fmt.Println(user.UpdateSecondTime > now.Unix()) // true
        fmt.Println(user.UpdateMilliTime > now.Unix())  // true
        fmt.Println(user.UpdateNanoTime > now.Unix())   // true
    }
    
    // 示例代码,仅供参考
    func newMongoClient() (*mongo.Client, error) {
        client, err := mongo.Connect(options.Client().ApplyURI("mongodb://localhost:27017").SetAuth(options.Credential{
            Username:   "test",
            Password:   "test",
            AuthSource: "db-test",
        }))
        if err != nil {
            return nil, err
        }
        err = client.Ping(context.Background(), readpref.Primary())
        if err != nil {
            panic(err)
        }
        return client, nil
    }

    updates 参数无需指定时间字段,也能自动填充。更新数据后,通过与 now 进行比较判断字段值是否被填充。fmt.Println 语句都输出 true,说明更新时间字段的值都已更新。

    Upsert 操作

    package main
    
    import (
        "context"
        "fmt"
        "time"
    
        "github.com/chenmingyong0423/go-mongox/v2/builder/query"
        "github.com/chenmingyong0423/go-mongox/v2/builder/update"
    
        "go.mongodb.org/mongo-driver/v2/bson"
    
        "go.mongodb.org/mongo-driver/v2/mongo"
        "go.mongodb.org/mongo-driver/v2/mongo/options"
        "go.mongodb.org/mongo-driver/v2/mongo/readpref"
    
        "github.com/chenmingyong0423/go-mongox/v2"
    )
    
    type User struct {
        ID        bson.ObjectID `bson:"_id,omitempty" mongoxpython:"autoID"`
        Name      string        `bson:"name"`
        Age       int           `bson:"age"`
        CreatedAt time.Time     `bson:"created_at"`
        UpdatedAt int           `bson:"updated_at"` // 使用秒级时间戳填充字段
    
        CreateSecondTime int64 `bson:"create_second_time" mongox:"autoCreateTime"`        // 使用秒级时间戳填充字段
        UpdateSecondTime int64 `bson:"update_second_time" mongox:"autoUpdateTime:second"` // 使用秒级时间戳填充字段
        CreateMilliTime  int64 `bson:"create_milli_time" mongox:"autoCreateTime:milli"`   // 使用毫秒级时间戳填充字段
        UpdateMilliTime  int64 `bson:"update_milli_time" mongox:"autoUpdateTime:milli"`   // 使用毫秒级时间戳填充字段
     php   CreateNanoTime   int64 `bson:"create_nano_time" mongox:"autoCreateTime:nano"`     // 使用纳秒级时间戳填充字段
        UpdateNanoTime   int64 `bson:"update_nano_time" mongox:"autoUpdateTime:nano"`     // 使用纳秒级时间戳填充字段
    }
    
    func main() {
        mongoClient, err := newMongoClient()
        if err != nil {
            panic(err)
        }
        client := mongox.NewClient(mongoClient, &mongox.Config{})
        database := client.NewDatabase("db-test")
    
        userColl := mongox.NewCollection[User](database, "users")
    
        _, err = userColl.Updater().
            Filter(query.Eq("name", "Mingyong Chen")).
            Updates(update.Set("age", 18)).
            Upsert(context.Background())
        if err != nil {
     android       panic(err)
        }
    
        user, err := userColl.Finder().
            Filter(query.Eq("name", "Mingyong Chen")).
            FindOne(context.Background())
        if err != nil {
            panic(err)
        }
    
        fmt.Println(!user.CreatedAt.IsZero())   // true
        fmt.Println(user.UpdatedAt != 0)        // true
        fmt.Println(user.CreateSecondTime != 0) // true
        fmt.Println(user.UpdateSecondTime != 0) // true
        fmt.Println(user.CreateMilliTime != 0)  // true
        fmt.Println(user.UpdateMilliTime != 0)  // true
        fmt.Println(user.CreateNanoTime != 0)  js // true
        fmt.Println(user.UpdateNanoTime != 0)   // true
    }
    
    // 示例代码,仅供参考
    func newMongoClient() (*mongo.Client, error) {
        client, err := mongo.Connect(options.Client().ApplyURI("mongodb://localhost:27017").SetAuth(optionwww.devze.coms.Credential{
            Username:   "test",
            Password:   "test",
            AuthSource: "db-test",
        }))
        if err != nil {
            return nil, err
        }
        err = client.Ping(context.Background(), readpref.Primary())
        if err != nil {
            panic(err)
        }
        return client, nil
    }

    当触发 Upsert 操作时,无需指定字段,创建时间和更新时间字段都会被填充。fmt.Println 语句都输出 true,说明所有时间字段的值都被填充。

    小结

    本文详细介绍了如何使用 mongox 库,在插入和更新数据时自动填充时间字段。在定义结构体时,只要满足 字段名称和类型符合规定字段包含特定标签mongox 将会自动填充时间字段的值。

    到此这篇关于Go Mongox轻松实现MongoDB的时间字段自动填充的文章就介绍到这了,更多相关Go Mongox使用内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜