golang MongoDB数据库操作插件库mgo的使用
golang MongoDB数据库操作插件库mgo的使用
MongoDB驱动 for Go
这个分支包含了一些我们自己做的改进以及从原始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)
}
}
主要特性
- 支持MongoDB 3.0-3.6版本
- 高性能的BSON编解码器
- 支持连接池和自动故障转移
- 支持索引、聚合、MapReduce等高级功能
- 支持MongoDB的读写关注(Read/Write Concern)
- 支持变更流(Change Streams)
- 支持排序规则(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)
注意事项
- 使用完毕后务必关闭Session
- 对于生产环境,建议配置连接池大小
- 注意处理网络错误和重连逻辑
- 考虑使用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)
性能优化
-
连接池管理:
session.SetPoolLimit(100) // 设置连接池大小 session.SetMode(mgo.Monotonic, true) // 设置一致性模式
-
批量查询优化:
query := collection.Find(bson.M{"age": bson.M{"$gt": 25}}) query.Batch(100) // 设置批量大小 query.Prefetch(0.25) // 设置预取比例
-
选择字段:
err = collection.Find(bson.M{"name": "张三"}).Select(bson.M{"name": 1, "email": 1}).One(&result)
注意事项
- mgo 已经不再积极维护,新项目建议使用官方驱动
go.mongodb.org/mongo-driver
- 确保正确处理错误和关闭会话
- 对于生产环境,考虑添加连接超时和重试逻辑
- 注意BSON和Go类型的映射关系
mgo 提供了简单直观的API,适合快速开发MongoDB应用。虽然它不再是官方推荐的选择,但在许多现有项目中仍然广泛使用。