golang 中操作 Mongo Update 的方法

tech2022-09-10  94

使用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 }

Update修改单条记录

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

和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) }

类似于mongodb语法:

db.getCollection('user').update( { "_id": ObjectId("56fdce98189df8759fd61e5b") }, { "age": 21} )

这边有一个小坑,就是这种写法的修改数据会更新整个文档为 {“age”: 21},而不是只更新age的值

更新前数据: { "_id" : ObjectId("56fdce98189df8759fd61e5b"), "name" : "Tom", "age" : 20 } 更新后数据: { "_id" : ObjectId("56fdce98189df8759fd61e5b"), "age" : 21 }

如果需要只更新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) }

如果更新的数据不存在,则会报一个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 }

由于Update只能更新一条数据,如果需要批量更新则需要使用UpdateAll函数 UpdateAll批量更新

func (c *Collection) UpdateAll(selector interface{}, update interface{}) (info *ChangeInfo, err error) 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>}

UpdateId根据Id更新 和Update函数类似,就是条件直接换成了objectid,这个使用也挺频繁的。

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

Upsert更新或者插入数据 这个函数就是如果数据存在就更新,否则就新增一条记录。这个函数也挺常用的。

func (c *Collection) Upsert(selector interface{}, update interface{}) (info *ChangeInfo, err error) 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>}

UpsertId按照更新或者插入数据

func (c *Collection) UpsertId(id interface{}, update interface{}) (info *ChangeInfo, err error) 类似 info, err := collection.Upsert(bson.M{"_id": id}, update) 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>} func UpsertPhoneInterface(_query, update bson.M) (err error) { query := func(c *mgo.Collection) error { _, err = c.Upsert(_query, update) return err } getCollection("perfInterface", query) return } q := bson.M{"serial": serial} p := bson.M{"serial": serial, "timestamp": stamptime, "ip": ip, "jtype": "serial-ip"} log.Info(q, p) err = db.UpsertPhoneInterface(q, p) if err != nil { ret := map[string]interface{}{"code": "000404", "msg": "fail to insert to mongodb"} return c.JSON(400, ret)
最新回复(0)