通过mongo-driver使用说明 GO 包管理机制

本篇记录通过GO语言操作mongodb,实现的流程包括:

  1. 初始化项目工程
  2. 容器方式安装mongo
  3. 调试运行和编译运行

go使用mongo的代码如下,go操作mongo的SDK是mongo-driver,一个第三方模块。本篇主要就是将其运行起来。


package main

import (
	"context"
	"fmt"
	"log"

	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"go.mongodb.org/mongo-driver/bson"
)

type Student struct {
	Name string
	Age int
}

func main() {
	// 设置客户端连接配置
	clientOptions := options.Client().ApplyURI("mongodb://admin:123456@localhost:27017")

	// 连接到MongoDB
	client, err := mongo.Connect(context.TODO(), clientOptions)
	if err != nil {
		log.Fatal(err)
	}

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


	collection := client.Database("q1mi").Collection("student")
    

        s1 := Student{"小红", 12}
	s2 := Student{"小兰", 10}
	s3 := Student{"小黄", 11}

	insertResult, err := collection.InsertOne(context.TODO(), s1)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("Inserted a single document: ", insertResult.InsertedID)

	students := []interface{}{s2, s3}
	insertManyResult, err := collection.InsertMany(context.TODO(), students)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Inserted multiple documents: ", insertManyResult.InsertedIDs)



	filter := bson.D{{"name", "小兰"}}

	// 创建一个Student变量用来接收查询的结果
	var result Student
	err = collection.FindOne(context.TODO(), filter).Decode(&result)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Found a single document: %+v\n", result)
}

创建GO项目工程

go之前对第三方包的管理不上心,其他语言比如python有pip,nodejs有npm,而go却没有一个官方的管理工具。

在go 1.11之前,开发者需要要关注GOPATH环境变量,这对于开发者来说不友好。

经过几次变更后,go于1.12版本开始正式使用go Module,go终于有了一个官方的处理方式,开发者也可以抛弃GOPATH了。

go的包管理包括:

  1. 创建一个目录做工程目录
  2. 初始化工程目录
  3. 设置包下载代理
  4. 安装依赖包

初始化开发工程

➜  go mkdir mongo
➜  go cd mongo

使用mod命令初始化

go mod init 文件名
➜ go mod init mongo
go: creating new go.mod: module mongo
➜ ls -al
total 8
drwxr-xr-x  3 ljk  staff   96  2  2 22:02 .
drwxr-xr-x  5 ljk  staff  160  2  2 22:02 ..
-rw-r--r--  1 ljk  staff   22  2  2 22:02 go.mod

初始化成功之后当前目录下会新建一个go.mod文件,用于记录安装的模块和包

➜  mongo cat go.mod
module mongo

go 1.18

设置包下载代理

go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.io,direct

安装mongo

下载 mongodb 镜像

➜  mod docker pull mongo:latest
latest: Pulling from library/mongo
70cf24b16239: Pull complete
197e79a59399: Pull complete
1a54d1916136: Pull complete
8547f0e899b2: Pull complete
315a8963db2b: Pull complete
0fce25e2f34f: Pull complete
1ce995f0f803: Pull complete
e3bfd9b7202d: Pull complete
07bd59396de7: Pull complete
Digest: sha256:3fe527dcddf277d4d5b278f5f03ddea5173cee84c792d12c5ac90c36ba40ba7a
Status: Downloaded newer image for mongo:latest
docker.io/library/mongo:latest
➜  mod docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
mongo        latest    b2fa76e584f6   20 hours ago   618MB
redis        5.0.4     b61ab367aee1   3 years ago    90MB

运行 mongodb 容器

➜  mod docker run -itd --name mongo -p 27017:27017 mongo --auth
f3116f4e2ed1d81e7707ee42b67c01fdcd648461e1e7cd35ad0815dae2c1af5f
➜  mod
➜  mod
➜  mod docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                      NAMES
f3116f4e2ed1   mongo     "docker-entrypoint.s…"   7 seconds ago   Up 6 seconds   0.0.0.0:27017->27017/tcp   mongo

登录 mongodb 容器并设置库权限

➜  mod docker exec -it mongo mongosh admin
Current Mongosh Log ID:	63dbcaa4fb21cc3d13dcfde2
Connecting to:		mongodb://127.0.0.1:27017/admin?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+1.6.2
Using MongoDB:		6.0.4
Using Mongosh:		1.6.2

For mongosh info see: https://docs.mongodb.com/mongodb-shell/


To help improve our products, anonymous usage data is collected and sent to MongoDB periodically (https://www.mongodb.com/legal/privacy-policy).
You can opt-out by running the disableTelemetry() command.

admin> db.createUser({ user:'admin',pwd:'123456',roles:[ { role:'userAdminAnyDatabase', db: 'admin'},"readWriteAnyDatabase"]});
{ ok: 1 }
admin> db.auth('admin', '123456')
{ ok: 1 }
admin>

调试运行

go run 可以直接下载依赖的模块,然后运行模块。

➜  mongo go run mongo_dev.go
go: downloading go.mongodb.org/mongo-driver v1.11.1
go: downloading github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d
go: downloading github.com/pkg/errors v0.9.1
go: downloading github.com/golang/snappy v0.0.1
go: downloading github.com/klauspost/compress v1.13.6
go: downloading github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe
go: downloading github.com/xdg-go/scram v1.1.1
go: downloading github.com/xdg-go/stringprep v1.0.3
go: downloading golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d
go: downloading golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
go: downloading golang.org/x/text v0.3.7
go: downloading github.com/xdg-go/pbkdf2 v1.0.0
Connected to MongoDB!
Inserted a single document:  ObjectID("63dbcaf83e1180444cc7dca1")
Inserted multiple documents:  [ObjectID("63dbcaf83e1180444cc7dca2") ObjectID("63dbcaf83e1180444cc7dca3")]
Found a single document: {Name:小兰 Age:10}

编译运行

如果想通过编译的方法运行程序而不是调试方法,可以通过一下三步:

  1. go mod tidy 自动更新需要的依赖文件
  2. go mod download 根据go.mod下载模块
  3. go build mongo_dev.go 编译go
  4. 执行go程序
➜  mongo_three go mod tidy
go: finding module for package go.mongodb.org/mongo-driver/mongo/options
go: finding module for package go.mongodb.org/mongo-driver/bson
go: finding module for package go.mongodb.org/mongo-driver/mongo
go: found go.mongodb.org/mongo-driver/bson in go.mongodb.org/mongo-driver v1.11.1
go: found go.mongodb.org/mongo-driver/mongo in go.mongodb.org/mongo-driver v1.11.1
go: found go.mongodb.org/mongo-driver/mongo/options in go.mongodb.org/mongo-driver v1.11.1
go: downloading github.com/google/go-cmp v0.5.2
go: downloading github.com/stretchr/testify v1.6.1
go: downloading github.com/tidwall/pretty v1.0.0
go: downloading github.com/kr/pretty v0.1.0
go: downloading github.com/kr/text v0.1.0
go: downloading github.com/davecgh/go-spew v1.1.1
go: downloading github.com/pmezard/go-difflib v1.0.0
go: downloading gopkg.in/yaml.v3 v3.0.1
go: downloading golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543

更新依赖文件之后,go.mod 文件中就记载了下载的模块信息,包括路径和版本信息

➜  mongo cat go.mod
module mongo

go 1.18

require (
	github.com/golang/snappy v0.0.1 // indirect
	github.com/klauspost/compress v1.13.6 // indirect
	github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
	github.com/pkg/errors v0.9.1 // indirect
	github.com/xdg-go/pbkdf2 v1.0.0 // indirect
	github.com/xdg-go/scram v1.1.1 // indirect
	github.com/xdg-go/stringprep v1.0.3 // indirect
	github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
	go.mongodb.org/mongo-driver v1.11.1 // indirect
	golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
	golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
	golang.org/x/text v0.3.7 // indirect
)

下载依赖的模块

➜  mongo go mod download

模块真正的文件放在gopath路径下的pkg路径下

~ go env 
.
.
GOPATH="/Users/ljk/Documents/go"

➜  mod pwd
/Users/ljk/Documents/go/pkg/mod
➜  mod ls
cache          github.com     go.mongodb.org golang.org

编译程序

➜  mongo go build mongo_dev.go
➜  mongo ls
go.mod       go.sum       mongo_dev    mongo_dev.go

执行可执行文件。

➜  mongo ./mongo_dev
Connected to MongoDB!
Inserted a single document:  ObjectID("63e1096ce7684b84e5b3229a")
Inserted multiple documents:  [ObjectID("63e1096ce7684b84e5b3229b") ObjectID("63e1096ce7684b84e5b3229c")]
Found a single document: {Name:小兰 Age:10}

可以看到程序连接到mongodb,并且写入了三条数据,查询了一次。

go 模块管理相关命令

go mod 相关命令

go mod download    下载依赖的module到本地cache(默认为$GOPATH/pkg/mod目录)
go mod edit        编辑go.mod文件
go mod graph       打印模块依赖图
go mod init        初始化当前文件夹, 创建go.mod文件
go mod tidy        增加缺少的module,删除无用的module
go mod vendor      将依赖复制到vendor下
go mod verify      校验依赖
go mod why         解释为什么需要依赖 

在go mod模块管理机制出现之前使用get和install命令管理模块。
go get是下载插件 和 go install 下载插件并编译程序。这些是1.12版本之前的模块管理方法,已经弃用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章