MongoDB的Go语言操作示例总结

2024-06-22 05:52

本文主要是介绍MongoDB的Go语言操作示例总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

前提条件

连接到MongoDB

简单示例

插入文档

查询文档

查询单个文档

查询多个文档

更新文档

更新单个文档

更新多个文档

删除文档

删除单个文档

删除多个文档

聚合管道

常见聚合操作符

$match

$group

$project

$sort

$limit

$skip

$lookup

$unwind

 示例

Go中的聚合管道使用示例

完整示例


MongoDB是一个流行的NoSQL数据库,而Go语言是一种简洁、高效的编程语言。这两者组合可以给应用程序提供强大的数据存储和操作能力。

在Go语言中操作MongoDB需要使用官方MongoDB Go驱动程序。以下总结下在Go语言中使用MongoDB数据库涉及到的一些基本操作。如插入文档、查询文档,如何在Go中进行连接、增、删、改、查等常用操作,以及如何使用聚合管道进行复杂查询。

前提条件

1.确保您已经安装了MongoDB和Go语言环境。

2.安装MongoDB Go驱动程序,可以使用go get命令来安装:

go get go.mongodb.org/mongo-driver/mongo

新建个项目文件夹,在下面新建main.go文件,执行yourprj换成你的包名。

go mod init yourprj

不用非得执行上面的go get 方式,直接项目代码中import需要的包,执行go mod tidy即可。 

连接到MongoDB

首先,需要连接到MongoDB实例:

package mainimport ("context""log""time""go.mongodb.org/mongo-driver/mongo""go.mongodb.org/mongo-driver/mongo/options"
)func main() {clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)defer cancel()client, err := mongo.Connect(ctx, clientOptions)if err != nil {log.Fatal(err)}defer func() {if err = client.Disconnect(ctx); err != nil {log.Fatal(err)}}()// 获取数据库和集合db := client.Database("testDB")collection := db.Collection("users")// 接下来的操作在这里进行
}

注意事项

上面的连接url参数针对未开启认证的可以连接成功,若开启有用户名密码验证则需要类似如下的连接参数:

"mongodb://user:yourpwd@localhost:27017/?tls=false&authSource=test1"

简单示例

package mainimport ("context""fmt""log""time"//"go.mongodb.org/mongo-driver/bson/primitive""go.mongodb.org/mongo-driver/mongo""go.mongodb.org/mongo-driver/mongo/options""go.mongodb.org/mongo-driver/bson"
)type User struct {Name  string `json:"name"`Email string `json:"email"`Age   int    `bson:"Agg"`
}
// ... 上面User结构体定义 ...func main() {// 连接MongoDBclientOptions := options.Client().ApplyURI("mongodb://test1:111111@localhost:27017/?tls=false&authSource=test1")client, err := mongo.Connect(context.Background(), clientOptions)if err != nil {log.Fatal(err)}defer func() {if err = client.Disconnect(context.Background()); err != nil {log.Fatal(err)}}()// 解析JSON字符串到User结构体(假设已经完成)user := User{Name: "Alice", Email: "alice@example.com",Age:22}// 选择数据库和集合collection := client.Database("test1").Collection("users")// 插入文档insertResult, err := collection.InsertOne(context.TODO(), user)if err != nil {log.Fatal(err)}fmt.Println("Inserted ID:", insertResult.InsertedID)// 插入文档doc := bson.D{{"age", 30},{"name", "Alice2"},  {"createdAt", time.Now()}}insertResult, err = collection.InsertOne(context.TODO(), doc)if err != nil {log.Fatal(err)}fmt.Println("Inserted ID:", insertResult.InsertedID)// 更新文档filter := bson.D{{"name", "Alice1"}}update := bson.D{{"$set", bson.D{{"age", 31}}}}updateResult, err := collection.UpdateOne(context.TODO(), filter, update)if err != nil {log.Fatal(err)}fmt.Println("Modified Count:", updateResult.ModifiedCount)// 删除文档filter = bson.D{{"age", 22}}deleteResult, err := collection.DeleteOne(context.TODO(), filter)if err != nil {log.Fatal(err)}fmt.Println("Deleted Count:", deleteResult.DeletedCount)// 查找单个文档var singleResult bson.Merr = collection.FindOne(context.TODO(), bson.D{}).Decode(&singleResult)if err != nil {log.Fatal(err)}fmt.Println("Single Document:", singleResult)// 查找所有文档cursor, err := collection.Find(context.TODO(), bson.D{})if err != nil {log.Fatal(err)}defer cursor.Close(context.TODO())for cursor.Next(context.TODO()) {var result bson.Merr := cursor.Decode(&result)if err != nil {log.Fatal(err)}fmt.Println("Document:", result)}// 过滤查找filteredCursor, err := collection.Find(context.TODO(), bson.D{{"age", bson.D{{"$gt", 31}}}})if err != nil {log.Fatal(err)}defer filteredCursor.Close(context.TODO())for filteredCursor.Next(context.TODO()) {var filteredDoc bson.Merr := filteredCursor.Decode(&filteredDoc)if err != nil {log.Fatal(err)}fmt.Println("Filtered Document:", filteredDoc)}
}

插入文档

    user := map[string]interface{}{"name": "Alice", "age": 29}_, err = collection.InsertOne(ctx, user)if err != nil {log.Fatal(err)}users := []interface{}{map[string]interface{}{"name": "Bob", "age": 31},map[string]interface{}{"name": "Charlie", "age": 25},}_, err = collection.InsertMany(ctx, users)if err != nil {log.Fatal(err)}

查询文档

查询单个文档

    var result map[string]interface{}filter := map[string]interface{}{"name": "Alice"}err = collection.FindOne(ctx, filter).Decode(&result)if err != nil {log.Fatal(err)}log.Println(result)

查询多个文档

    filter = map[string]interface{}{"age": map[string]interface{}{"$gte": 30}}cursor, err := collection.Find(ctx, filter)if err != nil {log.Fatal(err)}defer cursor.Close(ctx)var results []map[string]interface{}if err = cursor.All(ctx, &results); err != nil {log.Fatal(err)}for _, result := range results {log.Println(result)}

更新文档

更新单个文档

    filter = map[string]interface{}{"name": "Bob"}update := map[string]interface{}{"$set": map[string]interface{}{"age": 32}}_, err = collection.UpdateOne(ctx, filter, update)if err != nil {log.Fatal(err)}

更新多个文档

    filter = map[string]interface{}{"age": map[string]interface{}{"$lt": 30}}update = map[string]interface{}{"$set": map[string]interface{}{"valid": true}}_, err = collection.UpdateMany(ctx, filter, update)if err != nil {log.Fatal(err)}

删除文档

删除单个文档

    filter = map[string]interface{}{"name": "Charlie"}_, err = collection.DeleteOne(ctx, filter)if err != nil {log.Fatal(err)}

删除多个文档

    filter = map[string]interface{}{"valid": true}_, err = collection.DeleteMany(ctx, filter)if err != nil {log.Fatal(err)}

聚合管道

MongoDB的聚合管道(Aggregation Pipeline)是一种强大的数据处理工具,它允许用户对集合中的文档执行一系列数据转换和处理操作。聚合管道由一系列的阶段(stages)组成,每个阶段会对输入的文档进行一定的操作并将结果传递到下一个阶段。

每个阶段都是一个管道操作符(pipeline operator),共同组成一个管道。常见的管道操作符包括 $match$group$project$sort$limit 等。

聚合管道的基本结构
聚合管道通过 aggregate 方法来执行。其基本结构如下:db.collection.aggregate([{ $stage1: {...} },{ $stage2: {...} },...
])

常见聚合操作符

以下是一些常见的聚合操作符及其作用:

$match

用来过滤文档,其作用类似于 SQL 中的 WHERE 子句。

{ $match: { age: { $gte: 25 } } }

$group

将文档分组,并可以对每个分组应用聚合函数,如计数、求和、平均值等。

{ $group: { _id: "$age", count: { $sum: 1 } } }

$project

用于重新塑造文档,可以用来包括、排除或重命名字段。

{ $project: { name: 1, age: 1, _id: 0 } }

$sort

对文档进行排序。

{ $sort: { age: -1 } }

$limit

限制返回的文档数量。

{ $limit: 10 }

$skip

跳过指定数量的文档。

{ $skip: 5 }

$lookup

用于执行左外连接。

{ $lookup: { from: "otherCollection", localField: "fieldA", foreignField: "fieldB", as: "newField" } }

$unwind

将数组类型字段中的每个值拆分成单独的文档。

{ $unwind: "$arrayField" }

 示例

下面是一个使用 aggregate 方法的具体示例,展示了如何使用聚合管道操作符:

db.users.aggregate([// 匹配 age 大于等于 25 的文档{ $match: { age: { $gte: 25 } } },// 按照 age 分组,并计算每个分组的数量{ $group: { _id: "$age", count: { $sum: 1 } } },// 按照 count 字段降序排序{ $sort: { count: -1 } },// 仅保留前 5 个结果{ $limit: 5 }
])

Go中的聚合管道使用示例

package mainimport ("context""log""time""go.mongodb.org/mongo-driver/mongo""go.mongodb.org/mongo-driver/mongo/options"
)func main() {clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)defer cancel()client, err := mongo.Connect(ctx, clientOptions)if err != nil {log.Fatal(err)}defer func() {if err = client.Disconnect(ctx); err != nil {log.Fatal(err)}}()db := client.Database("testDB")collection := db.Collection("users")pipeline := mongo.Pipeline{{{Key: "$match", Value: map[string]interface{}{"age": map[string]interface{}{"$gte": 25}}}},{{Key: "$group", Value: map[string]interface{}{"_id": "$age", "count": map[string]interface{}{"$sum": 1}}}},{{Key: "$sort", Value: map[string]interface{}{"count": -1}}},{{Key: "$limit", Value: int32(5)}},}cursor, err := collection.Aggregate(ctx, pipeline)if err != nil {log.Fatal(err)}defer cursor.Close(ctx)var results []map[string]interface{}if err = cursor.All(ctx, &results); err != nil {log.Fatal(err)}for _, result := range results {log.Println(result)}
}
    pipeline := mongo.Pipeline{{{Key: "$match", Value: map[string]interface{}{"age": map[string]interface{}{"$gte": 25}}}},{{Key: "$group", Value: map[string]interface{}{"_id": "$age", "count": map[string]interface{}{"$sum": 1}}}},}cursor, err = collection.Aggregate(ctx, pipeline)if err != nil {log.Fatal(err)}defer cursor.Close(ctx)var pipelineResults []map[string]interface{}if err = cursor.All(ctx, &pipelineResults); err != nil {log.Fatal(err)}for _, result := range pipelineResults {log.Println(result)}

完整示例

package mainimport ("context""log""time""go.mongodb.org/mongo-driver/mongo""go.mongodb.org/mongo-driver/mongo/options"
)func main() {clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)defer cancel()client, err := mongo.Connect(ctx, clientOptions)if err != nil {log.Fatal(err)}defer func() {if err = client.Disconnect(ctx); err != nil {log.Fatal(err)}}()db := client.Database("testDB")collection := db.Collection("users")// 插入文档collection.InsertOne(ctx, map[string]interface{}{"name": "Alice", "age": 29})collection.InsertMany(ctx, []interface{}{map[string]interface{}{"name": "Bob", "age": 31},map[string]interface{}{"name": "Charlie", "age": 25},})// 查询单个文档var result map[string]interface{}collection.FindOne(ctx, map[string]interface{}{"name": "Alice"}).Decode(&result)log.Println(result)// 查询多个文档cursor, err := collection.Find(ctx, map[string]interface{}{"age": map[string]interface{}{"$gte": 30}})if err != nil {log.Fatal(err)}defer cursor.Close(ctx)var results []map[string]interface{}cursor.All(ctx, &results)for _, res := range results {log.Println(res)}// 更新文档collection.UpdateOne(ctx, map[string]interface{}{"name": "Bob"}, map[string]interface{}{"$set": map[string]interface{}{"age": 32}})collection.UpdateMany(ctx, map[string]interface{}{"age": map[string]interface{}{"$lt": 30}}, map[string]interface{}{"$set": map[string]interface{}{"valid": true}})// 删除文档collection.DeleteOne(ctx, map[string]interface{}{"name": "Charlie"})collection.DeleteMany(ctx, map[string]interface{}{"valid": true})// 聚合管道pipeline := mongo.Pipeline{{{Key: "$match", Value: map[string]interface{}{"age": map[string]interface{}{"$gte": 25}}}},{{Key: "$group", Value: map[string]interface{}{"_id": "$age", "count": map[string]interface{}{"$sum": 1}}}},}cursor, err = collection.Aggregate(ctx, pipeline)if err != nil {log.Fatal(err)}defer cursor.Close(ctx)var pipelineResults []map[string]interface{}cursor.All(ctx, &pipelineResults)for _, res := range pipelineResults {log.Println(res)}
}

这篇关于MongoDB的Go语言操作示例总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1083473

相关文章

Python函数作用域示例详解

《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

mysql表操作与查询功能详解

《mysql表操作与查询功能详解》本文系统讲解MySQL表操作与查询,涵盖创建、修改、复制表语法,基本查询结构及WHERE、GROUPBY等子句,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随... 目录01.表的操作1.1表操作概览1.2创建表1.3修改表1.4复制表02.基本查询操作2.1 SE

JavaSE正则表达式用法总结大全

《JavaSE正则表达式用法总结大全》正则表达式就是由一些特定的字符组成,代表的是一个规则,:本文主要介绍JavaSE正则表达式用法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录常用的正则表达式匹配符正则表China编程达式常用的类Pattern类Matcher类PatternSynta

Go语言中nil判断的注意事项(最新推荐)

《Go语言中nil判断的注意事项(最新推荐)》本文给大家介绍Go语言中nil判断的注意事项,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.接口变量的特殊行为2.nil的合法类型3.nil值的实用行为4.自定义类型与nil5.反射判断nil6.函数返回的

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

ModelMapper基本使用和常见场景示例详解

《ModelMapper基本使用和常见场景示例详解》ModelMapper是Java对象映射库,支持自动映射、自定义规则、集合转换及高级配置(如匹配策略、转换器),可集成SpringBoot,减少样板... 目录1. 添加依赖2. 基本用法示例:简单对象映射3. 自定义映射规则4. 集合映射5. 高级配置匹

c++中的set容器介绍及操作大全

《c++中的set容器介绍及操作大全》:本文主要介绍c++中的set容器介绍及操作大全,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录​​一、核心特性​​️ ​​二、基本操作​​​​1. 初始化与赋值​​​​2. 增删查操作​​​​3. 遍历方