这是我参与8月更文挑战的第23天,活动详情查看:8月更文挑战
简介
MongoDB是一个通用的,基于文档的分布式数据库,基于文档,既类似于JSON的文档内存储数据,所以非常适合处理json数据以及NoSQL型的日志数据
前几天刚刚发布了5.0.2版本,是一个新的大版本,更新了一大波功能,但比较可惜Robo3T这个工具目前只支持到4.2,所以这里依然以4.2版本为例
术语清晰表
| Mongo术语 | 说明 | SQL术语 | 说明 |
|---|---|---|---|
| database | 数据库 | database | 数据库 |
| collection | 集合 | table | 表 |
| document | 文档 | row | 行 |
| field | 字段 | column | 列 |
| index | 索引 | index | 索引 |
| primary key | 主键(id为主键) | primary key | 主键(自定义自增) |
安装
使用docker快速安装,往期传送门: juejin.cn/post/684490…
如果不想开启认证,将--auth参数 删除既可
docker run -itd --name mongo -p 27017:27017 mongo:4.2.6 --auth
笔者使用的GUI工具是Robo3T robomongo.org/download 现在下载需要输入邮箱信息,以前是不要的,如果介意的同学,可以找找以前的版本
客户端
基于go的mongo客户端,官方亲自下场了,且在github达到了6k星星,看来应该非常不错的了,
客户端地址: github.com/mongodb/mon…
要求是go大于1.10版本,mongodb2.6以上版本,现在的go都1.17了,不过博主目前用的1.16还没有升级。。
至于客户端对应的兼容性,目前最新的go driver是1.7版本,是支持mongo5.0的
官网说明: docs.mongodb.com/drivers/go/
api例子
初始化
将client和err定义全局变量,函数会经常用的,在项目启动检查连接状态,后续专注业务代码既可
var (
client *mongo.Client
err error
ctx = context.Background()
)
func init() {
//ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
// //defer cancel()
//连接mongodb
client, err = mongo.Connect(ctx, options.Client().ApplyURI("mongodb://ip:27017"))
if err != nil {
log.Fatalln("mongodb连接错误: ", err)
}
//连接检查
err = client.Ping(ctx,readpref.Primary())
if err != nil {
log.Fatalln("mongodb检查失败: ",err)
}
}
库和表结构
在mongo中,数据库名称和表都无须提前创建,因为mongo里面的数据都是bson对象,没有表结构一说,在写入数据时,就是把将库和表(如果没有)就直接创建了
bson
在go操作mongo的过程中,有一个模块在数据CURD中用来解码值,就是bson。
在mongo中的bson是一种数据格式,在go的客户端是具体实现mongo数据解析和加解码的工具包,有四种类型数据结构:
- bson.A{} 数组结构 是bson.D的数组类型
- bson.D{} k/v结构 {"name":"张三"}
- bson.M{} map结构 {{"name","李四"},{"age",1}}
- bson.E{} 是bson.D的bson元素,通常在bson.D{}里面使用
插入数据
插入单条数据
操作集合,拿到collection就可以。可以明显看出bson.M用起来更舒服一点
func insertOne() {
collection := client.Database("dev").Collection("person")
one, _ := collection.InsertOne(ctx, bson.M{"name": "法外狂徒张三", "age": 66})
one2, _ := collection.InsertOne(ctx, bson.D{{"name", "律政大享李三"}, {"age", 26}})
fmt.Println(one.InsertedID, one2.InsertedID)
_ = client.Disconnect(ctx)
}
插入多条数据
声明一个切片数据,调用InsertMany方法
这里可以看到InsertOne和InsertMany需要传入的参数都是一样的,在方法内部其实是有一个判断的区别
func insertMany() {
documents := []interface{}{
bson.M{"name":"精英律师王五","age":22},
bson.M{"name":"泼皮无赖赵六","age":23},
}
collection := client.Database("dev").Collection("person")
many, _ := collection.InsertMany(ctx,documents)
fmt.Println(many.InsertedIDs)
_ = client.Disconnect(ctx)
}
更新数据
在前面插入数据 把律政大享李三写错名字。。这里更新一下,弄成李四
更新方法需要2个参数,1个过滤条件,1个更新条件
官方例子 其实还加了个ops参数: options.Update().SetUpsert(true) 该参数的意思 如果没有根据fileter查询到结果,就作为新数据插入其中
func updateOne() {
filter := bson.D{{"name","律政大享李三"}}
update := bson.D{{"$set",bson.D{{"name","律政大享李四"}}}}
collection := client.Database("dev").Collection("person")
one, _ := collection.UpdateOne(ctx, filter, update)
fmt.Println(one.UpsertedCount)
_ = client.Disconnect(ctx)
}
现在看一下数据库时面的数据
查询数据
查询1条数据
查询需要传入1个过滤条件, 条件允许为空,直接返回第一条记录
空: bson.M{}
func findOne() {
filter := bson.M{"age":66}
collection := client.Database("dev").Collection("person")
one,_ := collection.FindOne(ctx, filter).DecodeBytes()
fmt.Println(one)
}
查询多条数据
默认是按照集合的数据先后进行输出,如果想改变加参数既可,数据条数也是一样,会输出全部,可以使用limit参数控制
func findMany() {
//设置排序
//opts := options.Find().SetSort(bson.D{{"age", 1}})
//设置返回结果条数
//options.Find().SetLimit(10)
collection := client.Database("dev").Collection("person")
find, _ := collection.Find(ctx, bson.M{})
var results []bson.M
_ = find.All(ctx, &results)
for _,result := range results {
fmt.Println(result)
}
}
统计数据
统计该集合所有数据总数
func count() {
collection := client.Database("dev").Collection("person")
documents, _ := collection.CountDocuments(ctx, bson.M{})
fmt.Println(documents)
}
删除数据
如果删除filter是字符串。可以设置忽略大小写 ops := options.Delete().SetCollation(&options.Collation{CaseLevel: false})
删除一条
func deleteOne() {
collection := client.Database("dev").Collection("person")
one, _ := collection.DeleteOne(ctx, bson.M{"age": 22})
fmt.Println(one.DeletedCount)
}
删除多条
如果过滤条件为空,那么将直接清空整个集群
func deleteMany() {
collection := client.Database("dev").Collection("person")
many, _ := collection.DeleteMany(ctx, bson.M{})
fmt.Println(many.DeletedCount)
}
总结
简单的练习了一下官方客户端的使用,较为高级和深入没有涉及,基本上的方法官方都给了例子,mongodb常用来做日志数据存储,地理位置信息存储等,可以基于以构建属于自已公司的日志系统