Go Mongox輕松實現(xiàn)MongoDB的時間字段自動填充
前言
在 MongoDB
的集合中,時間字段(如 創(chuàng)建時間 和 更新時間)通常是必不可少的。在使用 Go
語言操作 MongoDB
時,例如執(zhí)行插入或更新操作,我們需要手動設(shè)置這些時間字段的值。然而,每次手動賦值不僅繁瑣,還容易導(dǎo)致代碼重復(fù)。那么,是否可以在程序?qū)用鎸崿F(xiàn)自動填充呢?目前,官方的 mongo-go-driver
并不支持自動填充時間字段,而 mongox
庫提供了這一能力。本文將介紹如何使用 mongox
庫,在插入和更新數(shù)據(jù)時自動填充時間字段,從而提升開發(fā)效率并減少重復(fù)代碼。
時間字段填充規(guī)則
在定義結(jié)構(gòu)體時,如果字段符合以下特性,則可以被自動填充:
字段名稱和類型符合規(guī)定
結(jié)構(gòu)體字段名為 CreatedAt
和 UpdatedAt
字段,且類型為 time.Time
或 int/int64
。當為 int/int64
時,將會填充當前時間戳秒數(shù)。
字段包含特定標簽
mongox:"autoCreateTime"
:在插入文檔時,如果該字段的值為零值,則會自動設(shè)置為當前時間。除了time.Time
類型,你還可以使用second
、milli
和nano
三種時間戳精度,使用樣例:mongox:"autoCreateTime:milli"
如果不指定milli
,默認是second
。mongox:"autoUpdateTime"
:在插入文檔時,如果該字段的值為零值或更新文檔時,會自動設(shè)置為當前時間。除了time.Time
類型,你還可以使用second
、milli
和nano
三種時間戳精度。使用樣例:mongox:"autoUpdateTime:milli"
如果不指定milli
,默認是second
。
Mongox 的安裝
通過以下命令安裝 mongox
庫:
go get github.com/chenmingyong0423/go-mongox/v2
使用 Mongox 進行插入操作
結(jié)構(gòu)體定義
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 }
插入數(shù)據(jù)后,通過零值比較判斷字段值是否被填充。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
參數(shù)無需指定時間字段,也能自動填充。更新數(shù)據(jù)后,通過與 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" 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") _, err = userColl.Updater(). Filter(query.Eq("name", "Mingyong Chen")). Updates(update.Set("age", 18)). Upsert(context.Background()) if err != nil { 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) // 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 }
當觸發(fā) Upsert
操作時,無需指定字段,創(chuàng)建時間和更新時間字段都會被填充。fmt.Println
語句都輸出 true
,說明所有時間字段的值都被填充。
小結(jié)
本文詳細介紹了如何使用 mongox
庫,在插入和更新數(shù)據(jù)時自動填充時間字段。在定義結(jié)構(gòu)體時,只要滿足 字段名稱和類型符合規(guī)定 和 字段包含特定標簽,mongox
將會自動填充時間字段的值。
到此這篇關(guān)于Go Mongox輕松實現(xiàn)MongoDB的時間字段自動填充的文章就介紹到這了,更多相關(guān)Go Mongox使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
破解IDEA(Goland)注冊碼設(shè)置 license server一直有效不過期的過程詳解
這篇文章主要介紹了破解IDEA(Goland)注冊碼設(shè)置 license server一直有效不過期,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11go語言int64整型轉(zhuǎn)字符串的實現(xiàn)
本文主要介紹了go語言int64整型轉(zhuǎn)字符串的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03Golang多線程排序?qū)崿F(xiàn)快速高效地處理大規(guī)模數(shù)據(jù)
Golang多線程排序是一種快速高效地處理大規(guī)模數(shù)據(jù)的方法,通過使用Golang的協(xié)程和通道,可以將排序任務(wù)分配到多個線程中并行處理,提高了排序的效率和速度,需要詳細了解可以參考下文2023-05-05使用golang引入外部包的三種方式:go get, go module, ve
這篇文章主要介紹了使用golang引入外部包的三種方式:go get, go module, vendor目錄,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01