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