golang MongoDB数据库操作插件库mgo的使用

golang MongoDB数据库操作插件库mgo的使用

MongoDB驱动 for Go

Build Status GoDoc

这个分支包含了一些我们自己做的改进以及从原始mgo仓库合并的几个PR。更改主要针对性能改进和错误修复,但也添加了一些新功能。

详细的API文档可以在GoDoc上找到。

支持的版本

mgo 已知可以在MongoDB v3.0、3.2、3.4和3.6上良好工作。

MongoDB 4.0目前处于实验阶段 - 我们很乐意接受PR来帮助改进支持!

基本使用示例

下面是一个使用mgo进行MongoDB操作的完整示例:

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/globalsign/mgo"
	"github.com/globalsign/mgo/bson"
)

// Person 结构体定义
type Person struct {
	ID        bson.ObjectId `bson:"_id,omitempty"`
	Name      string
	Phone     string
	Timestamp time.Time
}

func main() {
	// 连接到MongoDB
	session, err := mgo.Dial("localhost")
	if err != nil {
		panic(err)
	}
	defer session.Close()

	// 设置一致性模式
	session.SetMode(mgo.Monotonic, true)

	// 获取数据库和集合
	c := session.DB("test").C("people")

	// 插入文档
	err = c.Insert(&Person{Name: "Alice", Phone: "+55 53 8116 9639", Timestamp: time.Now()},
		&Person{Name: "Bob", Phone: "+55 53 8402 8510", Timestamp: time.Now()})
	if err != nil {
		log.Fatal(err)
	}

	// 查询单个文档
	result := Person{}
	err = c.Find(bson.M{"name": "Alice"}).One(&result)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Phone:", result.Phone)

	// 查询多个文档
	var results []Person
	err = c.Find(bson.M{"name": bson.M{"$exists": true}}).All(&results)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Results All: ", results)

	// 更新文档
	colQuerier := bson.M{"name": "Alice"}
	change := bson.M{"$set": bson.M{"phone": "+86 99 8888 7777", "timestamp": time.Now()}}
	err = c.Update(colQuerier, change)
	if err != nil {
		log.Fatal(err)
	}

	// 删除文档
	err = c.Remove(bson.M{"name": "Bob"})
	if err != nil {
		log.Fatal(err)
	}
}

主要特性

  1. 支持MongoDB 3.0-3.6版本
  2. 高性能的BSON编解码器
  3. 支持连接池和自动故障转移
  4. 支持索引、聚合、MapReduce等高级功能
  5. 支持MongoDB的读写关注(Read/Write Concern)
  6. 支持变更流(Change Streams)
  7. 支持排序规则(Collations)

高级使用示例

// 使用索引
index := mgo.Index{
	Key:        []string{"name", "phone"}, // 复合索引
	Unique:     true,                      // 唯一索引
	DropDups:   true,                      // 删除重复项
	Background: true,                      // 后台创建
	Sparse:     true,                      // 稀疏索引
}

err = c.EnsureIndex(index)
if err != nil {
	log.Fatal(err)
}

// 聚合查询
pipe := c.Pipe([]bson.M{
	{"$match": bson.M{"name": bson.M{"$exists": true}}},
	{"$group": bson.M{"_id": "$name", "count": bson.M{"$sum": 1}}},
	{"$sort": bson.M{"count": -1}},
})
var aggregationResults []bson.M
err = pipe.All(&aggregationResults)
if err != nil {
	log.Fatal(err)
}
fmt.Println("Aggregation results:", aggregationResults)

注意事项

  1. 使用完毕后务必关闭Session
  2. 对于生产环境,建议配置连接池大小
  3. 注意处理网络错误和重连逻辑
  4. 考虑使用context来控制超时

mgo是一个成熟稳定的MongoDB驱动,适合大多数Go语言项目与MongoDB交互的需求。


更多关于golang MongoDB数据库操作插件库mgo的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang MongoDB数据库操作插件库mgo的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


mgo - Golang MongoDB 驱动使用指南

mgo 是 Go 语言的一个 MongoDB 驱动,提供了简单而强大的 MongoDB 操作接口。虽然目前官方推荐使用新的官方驱动 go.mongodb.org/mongo-driver,但 mgo 仍然被广泛使用。

安装 mgo

go get gopkg.in/mgo.v2

基本用法

1. 连接 MongoDB

package main

import (
	"fmt"
	"gopkg.in/mgo.v2"
	"log"
)

func main() {
	// 创建连接
	session, err := mgo.Dial("mongodb://localhost:27017")
	if err != nil {
		log.Fatal(err)
	}
	defer session.Close()

	// 检查连接是否正常
	err = session.Ping()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Connected to MongoDB!")
}

2. 选择数据库和集合

// 获取数据库
db := session.DB("testdb")

// 获取集合
collection := db.C("users")

// 或者直接通过session获取集合
collection := session.DB("testdb").C("users")

3. 插入文档

type User struct {
	Name  string
	Age   int
	Email string
}

user := User{
	Name:  "张三",
	Age:   30,
	Email: "zhangsan@example.com",
}

err = collection.Insert(&user)
if err != nil {
	log.Fatal(err)
}
fmt.Println("Document inserted!")

4. 查询文档

// 查询单个文档
var result User
err = collection.Find(bson.M{"name": "张三"}).One(&result)
if err != nil {
	log.Fatal(err)
}
fmt.Printf("Found document: %+v\n", result)

// 查询多个文档
var users []User
err = collection.Find(bson.M{"age": bson.M{"$gt": 25}}).All(&users)
if err != nil {
	log.Fatal(err)
}
fmt.Printf("Found %d documents\n", len(users))
for _, u := range users {
	fmt.Printf("%+v\n", u)
}

5. 更新文档

// 更新单个文档
err = collection.Update(
	bson.M{"name": "张三"},
	bson.M{"$set": bson.M{"age": 31}},
)
if err != nil {
	log.Fatal(err)
}

// 更新多个文档
_, err = collection.UpdateAll(
	bson.M{"age": bson.M{"$gt": 25}},
	bson.M{"$inc": bson.M{"age": 1}},
)
if err != nil {
	log.Fatal(err)
}

6. 删除文档

// 删除单个文档
err = collection.Remove(bson.M{"name": "张三"})
if err != nil {
	log.Fatal(err)
}

// 删除多个文档
_, err = collection.RemoveAll(bson.M{"age": bson.M{"$gt": 30}})
if err != nil {
	log.Fatal(err)
}

7. 索引操作

// 创建索引
index := mgo.Index{
	Key:        []string{"name", "email"},
	Unique:     true,
	DropDups:   true,
	Background: true,
	Sparse:     true,
}

err = collection.EnsureIndex(index)
if err != nil {
	log.Fatal(err)
}

// 删除索引
err = collection.DropIndex("name", "email")
if err != nil {
	log.Fatal(err)
}

高级特性

1. 批量操作

bulk := collection.Bulk()
bulk.Insert(User{Name: "李四", Age: 28, Email: "lisi@example.com"})
bulk.Insert(User{Name: "王五", Age: 35, Email: "wangwu@example.com"})
bulk.Update(bson.M{"name": "张三"}, bson.M{"$set": bson.M{"age": 32}})
_, err = bulk.Run()
if err != nil {
	log.Fatal(err)
}

2. 聚合操作

pipe := collection.Pipe([]bson.M{
	{"$match": bson.M{"age": bson.M{"$gt": 25}}},
	{"$group": bson.M{
		"_id":   "$age",
		"count": bson.M{"$sum": 1},
	}},
})

var results []bson.M
err = pipe.All(&results)
if err != nil {
	log.Fatal(err)
}
for _, res := range results {
	fmt.Printf("Age %v has %v users\n", res["_id"], res["count"])
}

3. 事务支持

// 注意:mgo本身不支持多文档事务,这是MongoDB 4.0+的特性
// 可以通过以下方式模拟简单事务

// 开始"事务"
session.SetSafe(&mgo.Safe{})

// 执行操作
err = collection.Insert(&User{Name: "赵六", Age: 40})
if err != nil {
	session.ResetSafe() // 回滚
	log.Fatal(err)
}

// 提交"事务"
session.SetSafe(nil)

性能优化

  1. 连接池管理:

    session.SetPoolLimit(100) // 设置连接池大小
    session.SetMode(mgo.Monotonic, true) // 设置一致性模式
    
  2. 批量查询优化:

    query := collection.Find(bson.M{"age": bson.M{"$gt": 25}})
    query.Batch(100) // 设置批量大小
    query.Prefetch(0.25) // 设置预取比例
    
  3. 选择字段:

    err = collection.Find(bson.M{"name": "张三"}).Select(bson.M{"name": 1, "email": 1}).One(&result)
    

注意事项

  1. mgo 已经不再积极维护,新项目建议使用官方驱动 go.mongodb.org/mongo-driver
  2. 确保正确处理错误和关闭会话
  3. 对于生产环境,考虑添加连接超时和重试逻辑
  4. 注意BSON和Go类型的映射关系

mgo 提供了简单直观的API,适合快速开发MongoDB应用。虽然它不再是官方推荐的选择,但在许多现有项目中仍然广泛使用。

回到顶部