go

使用go管理MongoDB

环境准备

测试MongoDB部署在k8s中,放开了nodeport。有用户名密码认证。

use golang;
db.createCollection("student");

file

安装驱动

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()
}

file

添加数据

使用的是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)
}

file

file

插入多条数据

使用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()
}

file

file

查找数据

使用的是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()
}

file

file

更新数据

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()
}

file

tom的age从30变为了25。

file

删除数据

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()
}

file

file

分类: go
0 0 投票数
文章评分
订阅评论
提醒
guest

0 评论
内联反馈
查看所有评论

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部
0
希望看到您的想法,请您发表评论x