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

相关文章

在C#中分离饼图的某个区域的操作指南

《在C#中分离饼图的某个区域的操作指南》在处理Excel饼图时,我们可能需要将饼图的各个部分分离出来,以使它们更加醒目,Spire.XLS提供了Series.DataFormat.Percent属性,... 目录引言如何设置饼图各分片之间分离宽度的代码示例:从整个饼图中分离单个分片的代码示例:引言在处理

Python列表的创建与删除的操作指南

《Python列表的创建与删除的操作指南》列表(list)是Python中最常用、最灵活的内置数据结构之一,它支持动态扩容、混合类型、嵌套结构,几乎无处不在,但你真的会创建和删除列表吗,本文给大家介绍... 目录一、前言二、列表的创建方式1. 字面量语法(最常用)2. 使用list()构造器3. 列表推导式

HTML5的input标签的`type`属性值详解和代码示例

《HTML5的input标签的`type`属性值详解和代码示例》HTML5的`input`标签提供了多种`type`属性值,用于创建不同类型的输入控件,满足用户输入的多样化需求,从文本输入、密码输入、... 目录一、引言二、文本类输入类型2.1 text2.2 password2.3 textarea(严格

MySQL中between and的基本用法、范围查询示例详解

《MySQL中betweenand的基本用法、范围查询示例详解》BETWEENAND操作符在MySQL中用于选择在两个值之间的数据,包括边界值,它支持数值和日期类型,示例展示了如何使用BETWEEN... 目录一、between and语法二、使用示例2.1、betwphpeen and数值查询2.2、be

python中的flask_sqlalchemy的使用及示例详解

《python中的flask_sqlalchemy的使用及示例详解》文章主要介绍了在使用SQLAlchemy创建模型实例时,通过元类动态创建实例的方式,并说明了如何在实例化时执行__init__方法,... 目录@orm.reconstructorSQLAlchemy的回滚关联其他模型数据库基本操作将数据添

Java数组动态扩容的实现示例

《Java数组动态扩容的实现示例》本文主要介绍了Java数组动态扩容的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1 问题2 方法3 结语1 问题实现动态的给数组添加元素效果,实现对数组扩容,原始数组使用静态分配

JAVA项目swing转javafx语法规则以及示例代码

《JAVA项目swing转javafx语法规则以及示例代码》:本文主要介绍JAVA项目swing转javafx语法规则以及示例代码的相关资料,文中详细讲解了主类继承、窗口创建、布局管理、控件替换、... 目录最常用的“一行换一行”速查表(直接全局替换)实际转换示例(JFramejs → JavaFX)迁移建

Go异常处理、泛型和文件操作实例代码

《Go异常处理、泛型和文件操作实例代码》Go语言的异常处理机制与传统的面向对象语言(如Java、C#)所使用的try-catch结构有所不同,它采用了自己独特的设计理念和方法,:本文主要介绍Go异... 目录一:异常处理常见的异常处理向上抛中断程序恢复程序二:泛型泛型函数泛型结构体泛型切片泛型 map三:文

C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解

《C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解》:本文主要介绍C++,C#,Rust,Go,Java,Python,JavaScript性能对比全面... 目录编程语言性能对比、核心优势与最佳使用场景性能对比表格C++C#RustGoJavapythonjav

MyBatis中的两种参数传递类型详解(示例代码)

《MyBatis中的两种参数传递类型详解(示例代码)》文章介绍了MyBatis中传递多个参数的两种方式,使用Map和使用@Param注解或封装POJO,Map方式适用于动态、不固定的参数,但可读性和安... 目录✅ android方式一:使用Map<String, Object>✅ 方式二:使用@Param