• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Go操作MongoDB数据库

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

MongoDB的Go驱动包

"go.mongodb.org/mongo-driver/bson"    //BOSN解析包
"go.mongodb.org/mongo-driver/mongo"    //MongoDB的Go驱动包
"go.mongodb.org/mongo-driver/mongo/options"
BSON简介

BSON是一种类json的一种二进制形式的存储格式,简称Binary JSON。MongoDB使用了BSON这种结构来存储数据和网络数据交换。

BSON对应Document这个概念,因为BSON是schema-free的,所以在MongoDB中所对应的Document也有这个特征,这里的一个Document也可以理解成关系数据库中的一条Record,只是Document的变化更丰富一些,Document可以嵌套。

MongoDB以BSON做为其存储结构的一个重要原因是它的可遍历性

BSON编码扩展了JSON表示,使其包含额外的类型,如int、long、date、浮点数和decimal128。

BSON类型

BSON数据的主要类型有:ADEMRaw。其中,A是数组,D是切片,M是映射,DM是Go原生类型。

  • A类型表示有序的BSON数组。

    bson.A{"bar", "world", 3.14159, bson.D{{"qux", 12345}}}
    
  • D类型表示包含有序元素的BSON文档。这种类型应该在顺序重要的情况下使用。如果元素的顺序无关紧要,则应使用M代替。

    bson.D{{"foo", "bar"}, {"hello", "world"}, {"pi", 3.14159}}
    
  • M类型表示无序的映射。

    bson.M{"foo": "bar", "hello": "world", "pi": 3.14159}
    
  • E类型表示D里面的一个BSON元素。

  • Raw类型代表未处理的原始BSON文档和元素,Raw系列类型用于验证和检索字节切片中的元素。当要查找BSON字节而不将其解编为另一种类型时,此类型最有用。

连接到mongoDB

// 设置mongoDB客户端连接信息
param := fmt.Sprintf("mongodb://XXX.XXX.XXX.XXX:27017")
clientOptions := options.Client().ApplyURI(param)

// 建立客户端连接
client, err := mongo.Connect(context.TODO(), clientOptions)
if err != nil {
log.Fatal(err)
fmt.Println(err)
}

// 检查连接情况
err = client.Ping(context.TODO(), nil)
if err != nil {
log.Fatal(err)
fmt.Println(err)
}
fmt.Println("Connected to MongoDB!")

//指定要操作的数据集
collection := client.Database("ccmsensor").Collection("mtr")

//执行增删改查操作

// 断开客户端连接
err = client.Disconnect(context.TODO())
if err != nil {
log.Fatal(err)
}
fmt.Println("Connection to MongoDB closed.")

增查改删

假如数据库中有一些网络连接数据,来自不同的APP,来自不同的ISP(运营商),类型如下:

type CurlInfo struct {
	DNS float64 `json:"NAMELOOKUP_TIME"` //NAMELOOKUP_TIME
	TCP float64 `json:"CONNECT_TIME"`    //CONNECT_TIME - DNS
	SSL float64 `json:"APPCONNECT_TIME"` //APPCONNECT_TIME - CONNECT_TIME
}

type ConnectData struct {
	Latency  float64  `json:"latency"`
	RespCode int      `json:"respCode"`
	Url      string   `json:"url"`
	Detail   CurlInfo `json:"details"`
}

type Sensor struct {
	ISP       string
	Clientutc int64
	DataByAPP map[string]ConnectData
}
增加

使用collection.InsertOne()来插入一条Document记录:

func insertSensor(client *mongo.Client, collection *mongo.Collection) (insertID primitive.ObjectID) {
	apps := make(map[string]ConnectData, 0)
	apps["app1"] = ConnectData{
		Latency:  30.983999967575,
		RespCode: 200,
		Url:      "",
		Detail: CurlInfo{
			DNS: 5.983999967575,
			TCP: 10.983999967575,
			SSL: 15.983999967575,
		},
	}
	
	record := &Sensor{
		Clientutc: time.Now().UTC().Unix(),
		ISP:       "China Mobile",
		DataByAPP: apps,
	}

	insertRest, err := collection.InsertOne(context.TODO(), record)
	if err != nil {
		fmt.Println(err)
		return
	}
	insertID = insertRest.InsertedID.(primitive.ObjectID)
	return insertID
}
查询

这里引入一个filter来匹配MongoDB数据库中的Document记录,使用bson.D类型来构建filter

timestamp := time.Now().UTC().Unix()
start := timestamp - 180
end := timestamp

filter := bson.D{
{"isp", isp},
{"$and", bson.A{
bson.D{{"clientutc", bson.M{"$gte": start}}},
bson.D{{"clientutc", bson.M{"$lte": end}}},
}},
}

使用collection.FindOne()来查询单个Document记录。这个方法返回一个可以解码为值的结果。

func querySensor(collection *mongo.Collection, isp string) {
	//查询一条记录

	//筛选数据
	timestamp := time.Now().UTC().Unix()
	start := timestamp - 1800
	end := timestamp

	filter := bson.D{
		{"isp", isp},
		{"$and", bson.A{
			bson.D{{"clientutc", bson.M{"$gte": start}}},
			bson.D{{"clientutc", bson.M{"$lte": end}}},
		}},
	}

	var original Sensor
	err := collection.FindOne(context.TODO(), filter).Decode(&original)
	if err != nil {
		fmt.Printf("%s\n", err.Error())
	}
	fmt.Printf("Found a single document: %+v\n", original)
}

结果为刚刚插入的那一条数据,

Connected to MongoDB!
Found a single document: {ISP:China Mobile Clientutc:1598867346 DataByAPP:map[app1:{Latency:30.983999967575 RespCode:200 Url: Detail:{DNS:5.983999967575 TCP:10.983999967575 SSL:15.983999967575}}]}
Connection to MongoDB closed.

若要提取其中的数据,在querySensor()方法中略作改动,

original := make(map[string]interface{})
var sensorData Sensor
err := collection.FindOne(context.TODO(), filter).Decode(&original)
if err != nil {
	fmt.Printf("%s\n", err.Error())
} else {
	vstr, okstr := original["isp"].(string)
	if okstr {
	sensorData.ISP = vstr
	}
}
更新

这里仍然使用刚才的filter,并额外需要一个update

update := bson.M{
"$set": bson.M{
"isp": ispAfter,
},
}

使用collection.UpdateOne()更新单个Document记录。

func UpdateSensor(collection *mongo.Collection, ispBefore string, ispAfter string) {
	//修改一条数据

	//筛选数据
	timestamp := time.Now().UTC().Unix()
	start := timestamp - 1800
	end := timestamp

	filter := bson.D{
		{"isp", ispBefore},
		{"$and", bson.A{
			bson.D{{"clientutc", bson.M{"$gte": start}}},
			bson.D{{"clientutc", bson.M{"$lte": end}}},
		}},
	}

	//更新内容
	update := bson.M{
		"$set": bson.M{
			"isp": ispAfter,
		},
	}

	updateResult, err := collection.UpdateOne(context.TODO(), filter, update)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Matched %v documents and updated %v documents.\n", updateResult.MatchedCount, updateResult.ModifiedCount)
}
删除

使用collection.DeleteOne()来删除一条记录,仍然使用刚才的filter。

deleteResult, err := collection.DeleteOne(context.TODO(), filter)
if err != nil {
	fmt.Printf("%s\n", err.Error())
}

更多操作请见官方文档。

参考链接

Mongo-Driver驱动包官方文档
BSON包官方文档
mongo包官方文档
options包官方文档


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
go【第一篇】go环境搭建发布时间:2022-07-10
下一篇:
hellofresh/janus: An API Gateway written in Go发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap