go中mgo操作数据库的一些示例

go中mgo操作数据库的一些示例

Posted by Hzy on December 25, 2019

 

博客:https://hzeyuan.cn


以前用的python,操作数据库用的是mongoengine,现在换成了go,发现了一个也挺不错的操作mongoDB驱动,mgo!

示例github地址:https://github.com/hzeyuan/learnGO/tree/master/mgo-examples


1.mgo的安装

go get gopkg.in/mgo.v2

github地址: https://github.com/go-mgo/mgo 如今已经停止维护了!

2. 下面是一些实际遇到的一些基本操作

2.0

开始前定义一些基本的变量

  • Posts结构体代表我们要存储的文章,
  • Seession:连接上mongo
  • Databse:是我们要创建的数据库名称
  • Collection:是我们创建的集合名称
1
2
3
4
5
6
7
8
9
10
11
12
type Posts struct {
	Title string
	Content string
	Date time.Time
}

var (
	Session,_ = mgo.Dial("localhost")
	Database = "mgo"
	Collection = "posts"
	Coll = Session.DB(Database).C(Collection)
)

2.1 删除数据库

1
2
3
4
5
6
7
// Drop Database
func DropDatebase(){
	fmt.Println("drop Database -->")
	if err :=Session.DB(Database).DropDatabase();err!=nil{
		fmt.Println("drop Datebase fail!!")
	}
}

2.2 添加一个文档

1
2
3
4
5
6
7
8
9
10
// 添加一个文档
func TestInsert(){
	fmt.Println("insert document to mongo DB -->")
	post1 := &Posts{
		Title:   "post1",
		Content: "post1-content",
		Date:    time.Now(),
	}
	Coll.Insert(post1)
}

2.3 添加多个文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 添加多个文档
func TestMultipleInsert(){
	t:=time.Now()
	fmt.Println("insert Multi document -->")
	var multiPosts []interface{}
	for i:=1;i<5001;i++{
		multiPosts = append(multiPosts,&Posts{
			Title:   fmt.Sprintf("post-%d",i),
			Content: fmt.Sprintf("post-%d-content",i),
			Date:    time.Now(),
		})
	}
	Coll.Insert(multiPosts...)
	fmt.Println(time.Since(t))
}

2.4 批量插入多个文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//批量插入
func TestBulkInsert(){
	t:=time.Now()
	fmt.Println("Bulk Insert -->")
	b :=Coll.Bulk()
	var bulkPosts []interface{}
	for i:=10;i<5010;i++{
		bulkPosts = append(bulkPosts,&Posts{
			Title:   fmt.Sprintf("post-%d",i),
			Content: fmt.Sprintf("post-%d-content",i),
			Date:    time.Now(),
		})
	}
	b.Insert(bulkPosts...)
	if _,err:=b.Run();err!=nil{
		fmt.Println(err)
	}
	fmt.Println(time.Since(t))
}

2.5 更新文档

1
2
3
4
5
6
7
8
9
//更新文档操作
func TestUpdate(){
	fmt.Println("Test Update in mongo DB -->")
	selector := bson.M{"title":"post1"}
	update :=bson.M{"$set":bson.M{"title":"post1-update"}}
	if err := Coll.Update(selector,update);err!=nil{
		fmt.Println(err)
	}
}

2.6 添加或者更新文档(upsert)

1
2
3
4
5
6
7
8
9
10
11
12
13
//添加或更新文档
func TestUpsert() {
	fmt.Println("Test Upsert in Mongo DB -->")

	//添加或者更新文档
	update := bson.M{"$set": bson.M{"content": "post-upsert-content"}}
	selector := bson.M{"title": "post-upsert-title"}

	_, err := Coll.Upsert(selector, update)
	if err != nil {
		panic(err)
	}
}

2.7 查询文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//查询文档
func TestSelect(){
	fmt.Println("Test Select in Mongo DB -->")
	var result Posts
	var results []Posts
	if err:=Coll.Find(bson.M{"title":"post1-update"}).One(&result);err!=nil{
		fmt.Println(err)
	}
	fmt.Printf("find one:%v\n",result)
	if err:=Coll.Find(bson.M{"title":"post1-update"}).All(&results);err!=nil{
		fmt.Println(err)
	}
	fmt.Printf("find all:%v\n",results)
	if err:=Coll.Find(bson.M{"title":"post1-update"}).All(&results);err!=nil{
		fmt.Println(err)
	}
	if err:=Coll.Find(bson.M{"title":"post1-update"}).Limit(1).All(&results);err!=nil{
		fmt.Println(err)
	}
	fmt.Printf("find limit:%v\n",results)
}

2.8 聚合操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//聚合操作
func TestAggregate(){
	pipeline := []bson.M{
		{"$match": bson.M{"title": "post1-update" }},
	}
	pipe := Coll.Pipe(pipeline)

	result := []bson.M{}
	//err := pipe.AllowDiskUse().All(&result) //allow disk use
	err := pipe.All(&result)
	if err != nil {
		panic(err)
	}
	fmt.Println("find TestAggregate result:", result)
}

2.9 直接将json保存到mongoDB中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func saveJsonToDB(){
	var f interface{}
	j:=[]byte(`{"posts": {
		"title": "post1",
		"content": "post1-content"
	}
}`)
	if err:=json.Unmarshal(j,&f);err!=nil{
		fmt.Println(err)
	}
	fmt.Printf("%v",&f)
	if err:=Coll.Insert(&f);err!=nil{
		fmt.Println(err)
	}

}

3.完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package main

import (
	"encoding/json"
	"fmt"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
	"time"
)

type Posts struct {
	Title string
	Content string
	Date time.Time
}

var (
	Session,_ = mgo.Dial("localhost")
	Database = "mgo"
	Collection = "posts"
	Coll = Session.DB(Database).C(Collection)
)

// Drop Database
func DropDatebase(){
	fmt.Println("drop Database -->")
	if err :=Session.DB(Database).DropDatabase();err!=nil{
		fmt.Println("drop Datebase fail!!")
	}
}

// 添加一个文档
func TestInsert(){
	fmt.Println("insert document to mongo DB -->")
	post1 := &Posts{
		Title:   "post1",
		Content: "post1-content",
		Date:    time.Now(),
	}
	Coll.Insert(post1)

}
// 添加多个文档
func TestMultipleInsert(){
	t:=time.Now()
	fmt.Println("insert Multi document -->")
	var multiPosts []interface{}
	for i:=1;i<5001;i++{
		multiPosts = append(multiPosts,&Posts{
			Title:   fmt.Sprintf("post-%d",i),
			Content: fmt.Sprintf("post-%d-content",i),
			Date:    time.Now(),
		})
	}
	Coll.Insert(multiPosts...)
	fmt.Println(time.Since(t))
}

//批量插入
func TestBulkInsert(){
	t:=time.Now()
	fmt.Println("Bulk Insert -->")
	b :=Coll.Bulk()
	var bulkPosts []interface{}
	for i:=10;i<5010;i++{
		bulkPosts = append(bulkPosts,&Posts{
			Title:   fmt.Sprintf("post-%d",i),
			Content: fmt.Sprintf("post-%d-content",i),
			Date:    time.Now(),
		})
	}
	b.Insert(bulkPosts...)
	if _,err:=b.Run();err!=nil{
		fmt.Println(err)
	}
	fmt.Println(time.Since(t))
}

//更新文档操作
func TestUpdate(){
	fmt.Println("Test Update in mongo DB -->")
	selector := bson.M{"title":"post1"}
	update :=bson.M{"$set":bson.M{"title":"post1-update"}}
	if err := Coll.Update(selector,update);err!=nil{
		fmt.Println(err)
	}
}

//添加或更新文档
func TestUpsert() {
	fmt.Println("Test Upsert in Mongo DB -->")

	//添加或者更新文档
	update := bson.M{"$set": bson.M{"content": "post-upsert-content"}}
	selector := bson.M{"title": "post-upsert-title"}

	_, err := Coll.Upsert(selector, update)
	if err != nil {
		panic(err)
	}
}

//查询文档
func TestSelect(){
	fmt.Println("Test Select in Mongo DB -->")
	var result Posts
	var results []Posts
	if err:=Coll.Find(bson.M{"title":"post1-update"}).One(&result);err!=nil{
		fmt.Println(err)
	}
	fmt.Printf("find one:%v\n",result)
	if err:=Coll.Find(bson.M{"title":"post1-update"}).All(&results);err!=nil{
		fmt.Println(err)
	}
	fmt.Printf("find all:%v\n",results)
	if err:=Coll.Find(bson.M{"title":"post1-update"}).All(&results);err!=nil{
		fmt.Println(err)
	}
	if err:=Coll.Find(bson.M{"title":"post1-update"}).Limit(1).All(&results);err!=nil{
		fmt.Println(err)
	}
	fmt.Printf("find limit:%v\n",results)
}

//聚合操作
func TestAggregate(){
	pipeline := []bson.M{
		{"$match": bson.M{"title": "post1-update" }},
	}
	pipe := Coll.Pipe(pipeline)

	result := []bson.M{}
	//err := pipe.AllowDiskUse().All(&result) //allow disk use
	err := pipe.All(&result)
	if err != nil {
		panic(err)
	}
	fmt.Println("find TestAggregate result:", result)
}

//保存json到mongo
func saveJsonToDB(){
	var f interface{}
	j:=[]byte(`{"posts": {
		"title": "post1",
		"content": "post1-content"
	}
}`)
	if err:=json.Unmarshal(j,&f);err!=nil{
		fmt.Println(err)
	}
	fmt.Printf("%v",&f)
	if err:=Coll.Insert(&f);err!=nil{
		fmt.Println(err)
	}

}
func main(){
	TestInsert()
	TestUpdate()
	TestUpsert()
	TestSelect()
	TestAggregate()
	TestMultipleInsert()
	TestBulkInsert()
	saveJsonToDB()
	defer Session.Close()
}