zoukankan      html  css  js  c++  java
  • 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", 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
    ", changeInfo)
    // 首次执行output: &{Updated:0 Removed:0 UpsertedId:ObjectIdHex("571df02ea99cff2c6826480b")}
    // 再次执行output: &{Updated:1 Removed:0 UpsertedId:<nil>}
  • 相关阅读:
    sass08 if while for each
    sass07 函数
    sass06 mixin
    sass05 数据类型,数据运算
    sass04 嵌套、继承、占位符
    批量导出docker images 的一个简单方法
    ARM 版本 瀚高 数据库的启动命令
    PHPStorm+Wamp+Xdebug+Windows7调试代码
    在Windows Server 2012 中安装 .NET 3.5 Framework
    Windows Server 2012 GUI与Core的切换
  • 原文地址:https://www.cnblogs.com/williamjie/p/9692660.html
Copyright © 2011-2022 走看看