环境准备
测试MongoDB部署在k8s中,放开了nodeport。有用户名密码认证。
use golang;
db.createCollection("student");
安装驱动
go get go.mongodb.org/mongo-driver
包地址为:https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo
连接MongoDB
使用的是这两个包:
go get go.mongodb.org/mongo-driver/mongo
go get go.mongodb.org/mongo-driver/mongo/options
使用的是client,ClientOptions函数中的方法。
func Connect(ctx context.Context, opts ...*options.ClientOptions) (*Client, error)
// Connect 创建一个新的 Client,然后使用 Connect 方法对其进行初始化。这等效于调用 NewClient,后跟 Client.Connect。
// 创建选项时。ClientOptions,调用方法的顺序很重要。以后的 Set* 方法将覆盖前面的 Set* 方法调用中的值。这包括 ApplyURI 方法。这允许调用方确定选项应用的优先顺序。例如,如果在 SetAuth 之前调用 ApplyURI,则 SetAuth 中的 Credential 将覆盖连接字符串中的值。如果在 SetAuth 之后调用 ApplyURI,则其值将覆盖 SetAuth 中的值。
// opts 参数使用选项进行处理。MergeClientOptions,它将覆盖先前选项的整个选项字段,没有部分覆盖。例如,如果在第一个选项的“身份验证”字段中设置了“用户名”,而为第二个选项设置了“密码”但没有“用户名”,则合并后,“用户名”字段将为空。
// NewClient 函数不执行任何 I/O,如果给定的选项无效,则返回错误。Client.Connect 方法启动后台 goroutine 来监视部署的状态,并且不会在主 goroutine 中执行任何 I/O 操作,以防止主 goroutine 阻塞。因此,如果部署关闭,它不会出错。
func (c *Client) Ping(ctx context.Context, rp *readpref.ReadPref) error
// Client.Ping 方法可用于验证部署是否已成功连接以及客户端是否已正确配置。rp 参数用于确定为操作选择的服务器。如果为 nil,则使用客户端的读取首选项。
func Client() *ClientOptions // Client 创建新的 ClientOptions 实例。
func (c *ClientOptions) ApplyURI(uri string) *ClientOptions
// ApplyURI 分析给定的 URI 并相应地设置选项。URI 可以包含主机名、IPv4/IPv6 文本或将在创建客户端时解析的 SRV 记录。使用 SRV 记录时,将隐式启用 TLS 支持。指定“tls=false”URI 选项以覆盖此选项。如果连接字符串包含以前设置的任何选项,它将覆盖这些选项。如果指定了任何查询参数,则对应于多个 URI 参数(如 WriteConcern)的选项将被完全覆盖。如果在调用此方法后在 ClientOptions 上设置了某个选项,则该选项将重写通过连接字符串应用的任何选项。
func (c *ClientOptions) SetAuth(auth Credential) *ClientOptions
// SetAuth 指定包含用于配置身份验证的选项的 Credential。请参阅选项。有关凭据字段的详细信息,请参阅凭据文档。默认值为空 Credential,表示不会配置任何身份验证。
init.go
package initdb
import (
"context"
"fmt"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"log"
)
var Client *mongo.Client
func InitDB() *mongo.Client {
credential := options.Credential{
Username: "root",
Password: "root",
}
clientOptions := options.Client().ApplyURI("mongodb://1.2.3.4:32333").SetAuth(credential)
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!")
Client = client
return Client
}
main.go
package main
import (
initdb "mongodb/initdb"
)
func main() {
initdb.InitDB()
}
添加数据
使用的是collection函数。Collection 是 MongoDB 集合的句柄。
添加单个数据
insert.go
func (coll *Collection) InsertOne(ctx context.Context, document interface{},
opts ...*options.InsertOneOptions) (*InsertOneResult, error)
// InsertOne 执行插入命令以将单个文档插入到集合中。document 参数必须是要插入的文档。它不能为零。如果文档在转换为 BSON 时没有_id字段,则会自动将一个字段添加到编组文档中。原始文档不会被修改。可以从返回的 InsertOneResult 的 InsertedID 字段中检索_id。opts 参数可用于指定操作的选项。
package insertdb
import (
"context"
"fmt"
"log"
"mongodb/initdb"
)
type Student struct {
Name string
Age int
}
func InsertDB(s Student) {
collection := initdb.Client.Database("golang").Collection("student")
res, err := collection.InsertOne(context.TODO(), s)
if err != nil {
log.Fatal(err)
}
fmt.Println("Inserted a single document: ", res.InsertedID)
}
main.go
package main
import (
"mongodb/initdb"
"mongodb/insertdb"
)
func main() {
initdb.InitDB()
s := insertdb.Student{Name: "ikun", Age: 25}
insertdb.InsertDB(s)
}
插入多条数据
使用bson包。包地址是:https://pkg.go.dev/go.mongodb.org/mongo-driver/bson
软件包 bson 是一个用于读取、写入和操作 BSON 的库。BSON 是一种二进制序列化格式,用于在 MongoDB 中存储文档和进行远程过程调用。BSON 扩展了 JSON,使其具有额外的类型,如int,long,date,浮点数等。使得应用程序更简单的对数据进行处理,排序。
mutiinsert.go
package insertdb
import (
"context"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
"log"
"mongodb/initdb"
)
func MutiInsertDB() {
collection := initdb.Client.Database("golang").Collection("student")
docs := []interface{}{
bson.D{{"name", "tom"}, {"age", 30}},
bson.D{{"name", "jerry"}, {"age", 20}},
}
opts := options.InsertMany().SetOrdered(false)
res, err := collection.InsertMany(context.TODO(), docs, opts)
if err != nil {
log.Fatal(err)
}
fmt.Println("Inserted a single document: ", res.InsertedIDs)
}
main.go
package main
import (
"mongodb/initdb"
"mongodb/insertdb"
)
func main() {
initdb.InitDB()
//s := insertdb.Student{Name: "ikun", Age: 25}
//insertdb.InsertDB(s)
insertdb.MutiInsertDB()
}
查找数据
使用的是find方法。
func (coll *Collection) Find(ctx context.Context, filter interface{},
opts ...*options.FindOptions) (cur *Cursor, err error)
// Find 执行 find 命令,并在集合中的匹配文档上返回 Cursor。filter 参数必须是包含查询运算符的文档,并且可用于选择结果中包含的文档。它不能为零。一个空文档(例如 bson.D{}) 应用于包含所有文档。opts 参数可用于指定操作的选项。
func (coll *Collection) FindOne(ctx context.Context, filter interface{},
opts ...*options.FindOneOptions) *SingleResult
// FindOne 执行 find 命令,并返回集合中一个文档的 SingleResult。filter 参数必须是包含查询运算符的文档,可用于选择要删除的文档。它不能为零。如果筛选器与任何文档不匹配,则将返回错误设置为 ErrNoDocuments 的 SingleResult。如果筛选器匹配多个文档,则将从匹配的集中选择一个文档。
func (coll *Collection) FindOneAndDelete(ctx context.Context, filter interface{},
opts ...*options.FindOneAndDeleteOptions) *SingleResult
// FindOneAndDelete 执行 findAndModify 命令,最多删除集合中的一个文档。并返回删除前的文档。
func (coll *Collection) FindOneAndReplace(ctx context.Context, filter interface{},
replacement interface{}, opts ...*options.FindOneAndReplaceOptions) *SingleResult
// FindOneAndReplace 执行 findAndModify 命令以替换集合中最多一个文档,并返回替换前显示的文档。替换参数必须是将用于替换所选文档的文档。它不能为 nil,并且不能包含任何更新运算符。
func (coll *Collection) FindOneAndUpdate(ctx context.Context, filter interface{},
update interface{}, opts ...*options.FindOneAndUpdateOptions) *SingleResult
// FindOneAndUpdate 执行 findAndModify 命令以更新集合中最多一个文档,并返回更新前显示的文档。update 参数必须是包含更新运算符的文档,并且可用于指定要对所选文档进行的修改。它不能为 nil 或为空。
findg.go
package findb
import (
"context"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"log"
"mongodb/initdb"
)
func Findb() {
collection := initdb.Client.Database("golang").Collection("student")
//opts := options.Find().SetSort(bson.D{{"age", 1}}) // 1 升序 -1 降序
//cursor, err := collection.Find(context.TODO(), bson.D{{"name", "ikun"}}, opts)
// 调用 Find 方法执行查询操作,将结果保存在 cursor 变量中。这里的查询条件是一个空的 BSON 文档 {},表示查询集合中的所有文档。
cursor, err := collection.Find(context.TODO(), bson.D{})
if err != nil {
log.Fatal(err)
}
// 关闭游标(cursor),释放数据库连接,避免资源泄漏。
defer cursor.Close(context.TODO())
var results []bson.M
// 使用 cursor.All 方法将查询结果解码为 []bson.M 类型的变量 results,并将查询到的文档保存在其中。
if err = cursor.All(context.TODO(), &results); err != nil {
log.Fatal(err)
}
for _, result := range results {
fmt.Println(result)
}
}
main.go
func main() {
initdb.InitDB()
//s := insertdb.Student{Name: "ikun", Age: 25}
//insertdb.InsertDB(s)
//insertdb.MutiInsertDB()
findb.Findb()
}
更新数据
func (coll *Collection) UpdateOne(ctx context.Context, filter interface{}, update interface{},
opts ...*options.UpdateOptions) (*UpdateResult, error)
// UpdateOne 执行更新命令以更新集合中最多一个文档。
func (coll *Collection) UpdateMany(ctx context.Context, filter interface{}, update interface{},
opts ...*options.UpdateOptions) (*UpdateResult, error)
// UpdateMany 执行更新命令以更新集合中的文档。
func (coll *Collection) UpdateByID(ctx context.Context, id interface{}, update interface{},
opts ...*options.UpdateOptions) (*UpdateResult, error)
// UpdateByID 执行更新命令以更新其 _id 值与集合中提供的 ID 匹配的文档。这等效于运行 UpdateOne(ctx, bson.D{{“_id”, id}}, 更新, 选择...).id 参数是要更新的文档的_id。它不能为零。如果 ID 与任何文档都不匹配,则操作将成功,并将返回 MatchedCount 为 0 的 UpdateResult。
update.go
package updatedb
import (
"context"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"log"
"mongodb/initdb"
)
func UpdateDB() {
collection := initdb.Client.Database("golang").Collection("student")
filter := bson.D{{"name", "tom"}}
update := bson.D{{"$set", bson.D{{"age", 25}}}}
result, err := collection.UpdateMany(context.TODO(), filter, update)
if err != nil {
log.Fatal(err)
}
if result.MatchedCount > 0 {
fmt.Printf("Matched %v documents and updated %v documents.\n", result.MatchedCount, result.ModifiedCount)
}
}
main.go
func main() {
initdb.InitDB()
//s := insertdb.Student{Name: "ikun", Age: 25}
//insertdb.InsertDB(s)
//insertdb.MutiInsertDB()
//findb.Findb()
updatedb.UpdateDB()
}
tom的age从30变为了25。
删除数据
func (coll *Collection) DeleteOne(ctx context.Context, filter interface{},
opts ...*options.DeleteOptions) (*DeleteResult, error)
// DeleteOne 执行删除命令,从集合中最多删除一个文档。
func (coll *Collection) DeleteMany(ctx context.Context, filter interface{},
opts ...*options.DeleteOptions) (*DeleteResult, error)
// DeleteMany 执行删除命令以从集合中删除文档。
delete.go
package deletedb
import (
"context"
"fmt"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
"log"
"mongodb/initdb"
)
func DeleteDB() {
collection := initdb.Client.Database("golang").Collection("student")
// 创建了一个 options.Delete 对象,并使用 SetCollation 方法设置了一个 options.Collation 对象。options.Collation 用于指定排序规则和比较方式
opts := options.Delete().SetCollation(&options.Collation{
//Locale: "en_US":指定排序规则和比较方式的语言环境为美国英语。这意味着在进行字符串比较时,会使用美国英语的排序规则。
//Strength: 1:指定字符串比较的强度为 1。在 MongoDB 中,字符串比较的强度范围是从 1 到 5,数字越高表示比较更为严格。在这里,强度为 1 表示进行基本的字符比较,不考虑变音符号、大小写等差异。
//CaseLevel: false:设置为 false,表示进行字符串比较时不区分大小写。这意味着在比较字符串时,不会考虑大小写的差异。"Tom"和"tom"都会匹配。
Locale: "en_US",
Strength: 1,
CaseLevel: false,
})
res, err := collection.DeleteMany(context.TODO(), bson.D{{"name", "Tom"}}, opts)
if err != nil {
log.Fatal(err)
}
fmt.Println("Deleted documents: ", res.DeletedCount)
}
main.go
func main() {
initdb.InitDB()
//s := insertdb.Student{Name: "ikun", Age: 25}
//insertdb.InsertDB(s)
//insertdb.MutiInsertDB()
//findb.Findb()
//updatedb.UpdateDB()
deletedb.DeleteDB()
}