三、go语言操作 mongodb mgo --go语言学习笔记

mgo使用指南

mgo简介
mgo(音mango)是MongoDB的Go语言驱动,它用基于Go语法的简单API实现了丰富的特性,并经过良好测试。

官方网站:http://labix.org/mgo

golang.tc(golangtc.com)网站的数据存储就是是用的MongoDB+mgo。近一年使用下来表现良好。

API文档
下面是mgo、mgo/bson、mgo/txn的在线文档。

mgo GoDoc GoWalker
mgo/bson GoDoc GoWalker
mgo/txn GoDoc GoWalker
安装
安装mgo之前请先安装Golang和MongoDB,安装过程不再赘述。

安装bzr版本工具(mgo使用Bazaar作为版本控制系统,因安装的时候需要去Bazaar拉取代码)。

安装命令

go get labix.org/v2/mgo
示例
下面的代码是个示例。

package main

import (
    "fmt"
    "labix.org/v2/mgo"
    "labix.org/v2/mgo/bson"
)

type Person struct {
    Name  string
    Phone string
}

func main() {
    session, err := mgo.Dial("")
    if err != nil {
        panic(err)
    }
    defer session.Close()

    // Optional. Switch the session to a monotonic behavior.
    session.SetMode(mgo.Monotonic, true)

    c := session.DB("test").C("people")
    err = c.Insert(&Person{"Ale", "+55 53 8116 9639"},
        &Person{"Cla", "+55 53 8402 8510"})
    if err != nil {
        panic(err)
    }

    result := Person{}
    err = c.Find(bson.M{"name": "Ale"}).One(&result)
    if err != nil {
        panic(err)
    }

    fmt.Println("Phone:", result.Phone)
}
启动MongoDB,把上面代码了跑一下,如果输出下面内容,说明安装成功。

Phone: +55 53 8116 9639
具体代码什么意思先不用管,后面讲解每个方法的用法。

如何使用
下面介绍如何使用mgo,主要介绍集合的操作。对数据库,用户等操作,请自行查看文档。

第一步当然是先导入mgo包

import (
    "labix.org/v2/mgo"
    "labix.org/v2/mgo/bson"
)
通过方法Dial()来和MongoDB服务器建立连接。Dial()定义如下:

func Dial(url string) (*Session, error)
具体使用:

session, err := mgo.Dial(url)
如果是本机,并且MongoDB是默认端口27017启动的话,下面几种方式都可以。

session, err := mgo.Dial("")
session, err := mgo.Dial("localhost")
session, err := mgo.Dial("127.0.0.1")
session, err := mgo.Dial("localhost:27017")
session, err := mgo.Dial("127.0.0.1:27017")
如果不在本机或端口不同,传入相应的地址即可。如:

mongodb://myuser:mypass@localhost:40001,otherhost:40001/mydb
通过Session.DB()来切换相应的数据库。

func (s *Session) DB(name string) *Database
如切换到test数据库。

db := session.DB("test")
通过Database.C()方法切换集合(Collection),这样我们就可以通过对集合进行增删查改操作了。

func (db *Database) C(name string) *Collection
如切换到`users`集合。

c := db.C("users")
介绍插入、查询、修改、删除操作。

先提一下ObjectId,MongoDB每个集合都会一个名为_id的主键,这是一个24位的16进制字符串。对应到mgo中就是bson.ObjectId。

这里我们定义一个struct,用来和集合对应。

type User struct {
    Id_       bson.ObjectId `bson:"_id"`
    Name      string        `bson:"name"`
    Age       int           `bson:"age"`
    JoinedAt   time.Time     `bson:"joined_at"`
    Interests []string      `bson:"interests"`
}
注解

注意User的字段首字母大写,不然不可见。通过bson:”name”这种方式可以定义MongoDB中集合的字段名,如果不定义,mgo自动把struct的字段名首字母小写作为集合的字段名。如果不需要获得id_,Id_可以不定义,在插入的时候会自动生成。

插入

插入方法定义如下:

func (c *Collection) Insert(docs ...interface{}) error
下面代码插入两条集合数据。

err = c.Insert(&User{
    Id_:       bson.NewObjectId(),
    Name:      "Jimmy Kuu",
    Age:       33,
    JoinedAt:  time.Now(),
    Interests: []string{"Develop", "Movie"},
})

if err != nil {
    panic(err)
}

err = c.Insert(&User{
    Id_:       bson.NewObjectId(),
    Name:      "Tracy Yu",
    Age:       31,
    JoinedAt:  time.Now(),
    Interests: []string{"Shoping", "TV"},
})

if err != nil {
    panic(err)
}
这里通过bson.NewObjectId()来创建新的ObjectId,如果创建完需要用到的话,放在一个变量中即可,一般在Web开发中可以作为参数跳转到其他页面。

通过MongoDB客户端可以发现,两条即可已经插入。

{ "_id" : ObjectId( "5204af979955496907000001" ),
  "name" : "Jimmy Kuu",
  "age" : 33,
  "joned_at" : Date( 1376038807950 ),
  "interests" : [
      "Develop",
      "Movie" ] }

{ "_id" : ObjectId( "5204af979955496907000002" ),
  "name" : "Tracy Yu",
  "age" : 31,
  "joned_at" : Date( 1376038807971 ),
  "interests" : [
      "Shoping",
      "TV" ] }
查询

通过func (c *Collection) Find(query interface{}) *Query来进行查询,返回的Query struct可以有附加各种条件来进行过滤。

通过Query.All()可以获得所有结果,通过Query.One()可以获得一个结果,注意如果没有数据或者数量超过一个,One()会报错。

条件用bson.M{key: value},注意key必须用MongoDB中的字段名,而不是struct的字段名。

无条件查询

查询所有

var users []User
c.Find(nil).All(&users)
fmt.Println(users)
上面代码可以把所有Users都查出来:

[{ObjectIdHex("5204af979955496907000001") Jimmy Kuu 33 2013-08-09 17:00:07.95 +0800 CST [Develop Movie]} {ObjectIdHex("5204af979955496907000002") Tracy Yu 31 2013-08-09 17:00:07.971 +0800 CST [Shoping TV]}]
根据ObjectId查询

id := "5204af979955496907000001"
objectId := bson.ObjectIdHex(id)

user := new(User)
c.Find(bson.M{"_id": objectId}).One(&user)

fmt.Println(user)
结果如下:

&{ObjectIdHex("5204af979955496907000001") Jimmy Kuu 33 2013-08-09 17:00:07.95 +0800 CST [Develop Movie]}
更简单的方式是直接用FindId()方法:

c.FindId(objectId).One(&user)
注解

注意这里没有处理err。当找不到的时候用One()方法会出错。

单条件查询

=($eq)
c.Find(bson.M{"name": "Jimmy Kuu"}).All(&users)
!=($ne)
c.Find(bson.M{"name": bson.M{"$ne": "Jimmy Kuu"}}).All(&users)
>($gt)
c.Find(bson.M{"age": bson.M{"$gt": 32}}).All(&users)
<($lt)
c.Find(bson.M{"age": bson.M{"$lt": 32}}).All(&users)
>=($gte)
c.Find(bson.M{"age": bson.M{"$gte": 33}}).All(&users)
<=($lte)
c.Find(bson.M{"age": bson.M{"$lte": 31}}).All(&users)
in($in)
c.Find(bson.M{"name": bson.M{"$in": []string{"Jimmy Kuu", "Tracy Yu"}}}).All(&users)
多条件查询

and($and)
c.Find(bson.M{"name": "Jimmy Kuu", "age": 33}).All(&users)
or($or)
c.Find(bson.M{"$or": []bson.M{bson.M{"name": "Jimmy Kuu"}, bson.M{"age": 31}}}).All(&users)
修改

通过func (*Collection) Update来进行修改操作。

func (c *Collection) Update(selector interface{}, change interface{}) error
注意修改单个或多个字段需要通过$set操作符号,否则集合会被替换。

修改字段的值($set)

c.Update(bson.M{"_id": bson.ObjectIdHex("5204af979955496907000001")},
    bson.M{"$set": bson.M{
        "name": "Jimmy Gu",
        "age":  34,
    }})
inc($inc)

字段增加值

c.Update(bson.M{"_id": bson.ObjectIdHex("5204af979955496907000001")},
    bson.M{"$inc": bson.M{
        "age": -1,
    }})
push($push)

从数组中增加一个元素

c.Update(bson.M{"_id": bson.ObjectIdHex("5204af979955496907000001")},
    bson.M{"$push": bson.M{
        "interests": "Golang",
    }})
pull($pull)

从数组中删除一个元素

c.Update(bson.M{"_id": bson.ObjectIdHex("5204af979955496907000001")},
    bson.M{"$pull": bson.M{
        "interests": "Golang",
    }})
删除

c.Remove(bson.M{"name": "Jimmy Kuu"})
注解

这里也支持多条件,参考多条件查询。



其余示例一:


github:  https://github.com/ZhangzheBJUT/blog/blob/master/mgo.md

注:现在MongoDB官方还没有推出关于官方支持的golang的driver,推荐使用的是mgo, mgo的详细文档说明:http://godoc.org/labix.org/v2/mgo
下面是开发中自己写的一个用mgo连接MongoDB数据库的使用实例。

package main


import (

    "fmt"
    "labix.org/v2/mgo"
    "labix.org/v2/mgo/bson"
)

type Person struct {
    NAME  string
    PHONE string
}
type Men struct {
    Persons []Person
}
const = (
    URL = "192.168.2.175:27017"
)
func main() {

    session, err := mgo.Dial(URL)  //连接数据库
    if err != nil {
        panic(err)
    }
    defer session.Close()
    session.SetMode(mgo.Monotonic, true)

    db := session.DB("mydb")     //数据库名称
    collection := db.C("person") //如果该集合已经存在的话,则直接返回


    //*集合中元素数目
    countNum, err := collection.Count()
    if err != nil {
        panic(err)
    }
    fmt.Println("Things objects count: ", countNum)

    //*插入元素*
    temp := &Person{
        PHONE: "18811577546",
        NAME:  "zhangzheHero"
    }
        //一次可以插入多个对象 插入两个Person对象
    err = collection.Insert(&Person{"Ale", "+55 53 8116 9639"}, temp)
    if err != nil {
        panic(err)
    }

    //*查询单条数据*
    result := Person{}
    err = collection.Find(bson.M{"phone": "456"}).One(&result)
    fmt.Println("Phone:", result.NAME, result.PHONE)

    //*查询多条数据*
    var personAll Men  //存放结果
    iter := collection.Find(nil).Iter()
    for iter.Next(&result) {
        fmt.Printf("Result: %v\n", result.NAME)
        personAll.Persons = append(personAll.Persons, result)
    }

    //*更新数据
    err = collection.Update(bson.M{"name": "ccc"}, bson.M{"$set": bson.M{"name": "ddd"}})
    err = collection.Update(bson.M{"name": "ddd"}, bson.M{"$set": bson.M{"phone": "12345678"}})
    err = collection.Update(bson.M{"name": "aaa"}, bson.M{"phone": "1245", "name": "bbb"})

    //删除数据
    _, err = collection.RemoveAll(bson.M{"name": "Ale”})
} 

其余示例二:

https://docs.compose.io/languages/golang.html
https://gist.github.com/border/3489566

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
### 回答1: 在使用 Go 语言操作 MongoDB 数据库时,可以使用事务来管理写入、删除等操作。 首先,在开启事务之前,需要先获取一个 MongoDB 连接: ``` client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017")) if err != nil { // handle error } ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) defer cancel() err = client.Connect(ctx) if err != nil { // handle error } ``` 然后,可以使用 `client.Database()` 方法来获取数据库的句柄,再使用 `Database.StartSession()` 方法来开启一个事务: ``` sess, err := client.Database("mydb").StartSession() if err != nil { // handle error } defer sess.EndSession(ctx) ``` 在事务中执行写入、删除等操作时,需要使用 `Session.WithTransaction()` 方法来包裹这些操作,并使用 `Session.AbortTransaction()` 方法来回滚事务: ``` err = sess.WithTransaction(ctx, func(sessCtx mongo.SessionContext) error { // perform write operations _, err = client.Database("mydb").Collection("mycoll").InsertOne(sessCtx, bson.M{"x": 1}) if err != nil { sess.AbortTransaction(sessCtx) return err } return nil }) if err != nil { // handle error } ``` 在事务中执行的所有操作都会在事务提交之前保存到内存中,并在事务提交时一起写入到数据库中。如果在事务中出现了错误,可以使用 `Session.AbortTransaction()` 方法来回滚事务,所有在事务中执行的操作都不会写入到数据库中。 在事务结 ### 回答2: 在Go语言操作MongoDB,可以使用事务回滚来进行写入、删除等操作。以下是一些基本操作的示例: 1. 初始化MongoDB客户端和数据库连接: ```go clientOptions := options.Client().ApplyURI("mongodb://localhost:27017") client, err := mongo.Connect(context.TODO(), clientOptions) if err != nil { log.Fatal(err) } database := client.Database("mydatabase") ``` 2. 开启事务: ```go session, err := client.StartSession() if err != nil { log.Fatal(err) } defer session.EndSession(context.TODO()) ``` 3. 事务开始后,可以执行多个操作。例如,插入一条数据: ```go session.StartTransaction() collection := database.Collection("mycollection") doc := bson.D{{"key", "value"}} _, err = collection.InsertOne(session.Context(), doc) if err != nil { session.AbortTransaction(session.Context()) log.Fatal(err) } ``` 4. 执行其他操作,比如删除一条数据: ```go collection := database.Collection("mycollection") filter := bson.D{{"key", "value"}} _, err = collection.DeleteOne(session.Context(), filter) if err != nil { session.AbortTransaction(session.Context()) log.Fatal(err) } ``` 5. 若所有操作都成功执行,提交事务: ```go err = session.CommitTransaction(session.Context()) if err != nil { log.Fatal(err) } ``` 6. 若操作发生错误或者需要回滚,可以调用AbortTransaction()进行事务回滚: ```go session.AbortTransaction(session.Context()) ``` 以上是一个简单的示例,用于展示如何在Go语言中使用事务回滚进行写入和删除操作。实际应用中,可能需要更多的代码和逻辑来处理错误以及处理更复杂的事务操作

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值