Golang 中操作 Mongo Update 的方法


Golang 和 MongoDB 中的 ISODate 時間交互問題

版權聲明:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/u010649766/article/details/79385948

MongoDB 中有一種時間格式數據 ISODate,參考如下: 
mongodb中的時間

如果在 Golang 中查詢這條記錄,Golang用什么類型的變量來保存呢?

查找 ISODate 時間字段

在 Golang 中可以使用 time.Time 數據類型來保存 MongoDB 中的 ISODate 時間。

type Model struct {
    Id   bson.ObjectId `bson:"_id,omitempty"` Time time.Time `bson:"time"` } m := Model{} err := c.Find(bson.M{"_id": bson.ObjectIdHex("572f3c68e43001d2c1703aa7")}).One(&m) if err != nil { panic(err) } fmt.Printf("%+v\n", m) // output: {Id:ObjectIdHex("572f3c68e43001d2c1703aa7") Time:2015-07-08 17:29:14.002 +0800 CST}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

從輸出中可以看到 Golang 輸出的時間格式是 CST 時區,Golang 在處理的過程中將 ISO 時間轉換成了 CST 時間,從時間面板上來看也比 MongoDB 中的快上 8 個小時,這個是正常的。

那么 Golang 做插入操作和或者時間比較操作的時候需要自己轉換時間戳嗎?答案是不需要的,來看下插入的例子。

插入時間

重新插入一條記錄,記錄的Time字段為當前時間,在golang中可以通過time.Now獲取當前時間,查看輸出可以看到是CST的時間格式

now := time.Now()
fmt.Printf("%+v\n", now) // output: 2016-05-12 14:34:00.998011694 +0800 CST err = c.Insert(Model{Time: now}) if err != nil { panic(err) }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

查看 MongoDB 中的記錄

插入當前時間到 MongoDB: 
插入當前時間到MongoDB

可以看到存儲到 MongoDB 中時間的自動轉換為了 ISO 時間,時間少了 8 個小時。小結一下就是 Golang 和 MongoDB 中的時間交互不需要考慮額外的東西,因為驅動都進行了轉換。

時間字符串轉成 time.Time

有時我們會將 time.Time 的時間以字符串的形式存儲,那么要和 MongoDB 交互的時候就需要轉換 time.Time 格式

// 時間字符串轉到到time.Time格式 // 使用time.Parse方法進行轉換 timeString := "2016-05-12 14:34:00.998011694 +0800 CST" t, err := time.Parse("2006-01-02 15:04:05.999999999 -0700 MST", timeString) if err != nil { panic(err) } fmt.Printf("%+v\n", t)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

代碼中比較難理解的就是 time.Parse 的第一個參數,這個其實是 Golang 當中的定義,詳細看下 time.Time.String() 的源碼就會明白了。

 

 

 

 

這篇博客主要記錄下 Golang 中引入 Mongo 數據庫對 Mongo 的修改操作的方法。

使用gopkg.in/mgo.v2庫操作,修改操作主要使用mongodb中Collection對象的Update、UpdateAll、UpdateId、Upsert、UpsertId方法。

統一封裝下getDB方法

package main import ( "fmt" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" ) // get mongodb db func getDB() *mgo.Database { session, err := mgo.Dial("127.0.0.1:27017") if err != nil { panic(err) } session.SetMode(mgo.Monotonic, true) db := session.DB("test") return db }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

Update修改單條記錄

func (c *Collection) Update(selector interface{}, update interface{}) error
  • 1

和mysql不同,Update函數只能用來修改單條記錄,即使條件能匹配多條記錄,也只會修改第一條匹配的記錄。

selector := bson.M{"_id": bson.ObjectIdHex("56fdce98189df8759fd61e5b")} data := bson.M{"age": 21} err := getDB().C("user").Update(selector, data) if err != nil { panic(err) }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

類似於mongodb語法:

db.getCollection('user').update( { "_id": ObjectId("56fdce98189df8759fd61e5b") }, { "age": 21} )
  • 1
  • 2
  • 3
  • 4

這邊有一個小坑,就是這種寫法的修改數據會更新整個文檔為 {“age”: 21},而不是只更新age的值。

 更新前數據:
    {
        "_id" : ObjectId("56fdce98189df8759fd61e5b"), "name" : "Tom", "age" : 20 } 更新后數據: { "_id" : ObjectId("56fdce98189df8759fd61e5b"), "age" : 21 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

如果需要只更新age的值,則需要使用$set關鍵詞:

selector := bson.M{"_id": bson.ObjectIdHex("571de968a99cff2c68264807")} data := bson.M{"$set": bson.M{"age": 21}} err := getDB().C("user").Update(selector, data) if err != nil { panic(err) } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

如果更新的數據不存在,則會報一個not found的錯誤:

// 更新不存在的數據
selector := bson.M{"_id": bson.ObjectIdHex("16fdce98189df8759fd61e5b")} data := bson.M{"age": 21} err := getDB().C("user").Update(selector, data) if err != nil { fmt.Println(err == mgo.ErrNotFound) // output: true }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

由於Update只能更新一條數據,如果需要批量更新則需要使用UpdateAll函數

UpdateAll批量更新

func (c *Collection) UpdateAll(selector interface{}, update interface{}) (info *ChangeInfo, err error) 
  • 1
  • 2
selector := bson.M{"name": "Tom"} data := bson.M{"$set": bson.M{"age": 22}} changeInfo, err := getDB().C("user").UpdateAll(selector, data) if err != nil { panic(err) } fmt.Printf("%+v\n", changeInfo) // output: &{Updated:2 Removed:0 UpsertedId:<nil>} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

UpdateId根據Id更新 
和Update函數類似,就是條件直接換成了objectid,這個使用也挺頻繁的。

func (c *Collection) UpdateId(id interface{}, update interface{}) error 類似 err := collection.Update(bson.M{"_id": id}, update) 
  • 1
  • 2
  • 3
id := bson.ObjectIdHex("571de968a99cff2c68264807") data := bson.M{"$set": bson.M{"age": 30}} err := getDB().C("user").UpdateId(id, data) if err != nil { panic(err) }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Upsert更新或者插入數據 
這個函數就是如果數據存在就更新,否則就新增一條記錄。這個函數也挺常用的。

func (c *Collection) Upsert(selector interface{}, update interface{}) (info *ChangeInfo, err error)
  • 1
selector := bson.M{"key": "max"} data := bson.M{"$set": bson.M{"value": 30}} changeInfo, err := getDB().C("config").Upsert(selector, data) if err != nil { panic(err) } fmt.Printf("%+v\n", changeInfo) // 首次執行output: &{Updated:0 Removed:0 UpsertedId:ObjectIdHex("571df02ea99cff2c6826480a")} // 再次執行output: &{Updated:1 Removed:0 UpsertedId:<nil>}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

UpsertId按照更新或者插入數據

 func (c *Collection) UpsertId(id interface{}, update interface{}) (info *ChangeInfo, err error) 類似 info, err := collection.Upsert(bson.M{"_id": id}, update)
  • 1
  • 2
  • 3
id := bson.ObjectIdHex("571df02ea99cff2c6826480b") data := bson.M{"$set": bson.M{"key": "max", "value": 30}} changeInfo, err := getDB().C("config").UpsertId(id, data) if err != nil { panic(err) } fmt.Printf("%+v\n", changeInfo) // 首次執行output: &{Updated:0 Removed:0 UpsertedId:ObjectIdHex("571df02ea99cff2c6826480b")} // 再次執行output: &{Updated:1 Removed:0 UpsertedId:<nil>}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM