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语言中联合体union的使用

本文编辑整理自: http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=179471 一、前言 “联合体”(union)与“结构体”(struct)有一些相似之处。但两者有本质上的不同。在结构体中,各成员有各自的内存空间, 一个结构变量的总长度是各成员长度之和。而在“联合”中,各成员共享一段内存空间, 一个联合变量

关于C++中的虚拟继承的一些总结(虚拟继承,覆盖,派生,隐藏)

1.为什么要引入虚拟继承 虚拟继承是多重继承中特有的概念。虚拟基类是为解决多重继承而出现的。如:类D继承自类B1、B2,而类B1、B2都继承自类A,因此在类D中两次出现类A中的变量和函数。为了节省内存空间,可以将B1、B2对A的继承定义为虚拟继承,而A就成了虚拟基类。实现的代码如下: class A class B1:public virtual A; class B2:pu

RedHat运维-Linux文本操作基础-AWK进阶

你不用整理,跟着敲一遍,有个印象,然后把它保存到本地,以后要用再去看,如果有了新东西,你自个再添加。这是我参考牛客上的shell编程专项题,只不过换成了问答的方式而已。不用背,就算是我自己亲自敲,我现在好多也记不住。 1. 输出nowcoder.txt文件第5行的内容 2. 输出nowcoder.txt文件第6行的内容 3. 输出nowcoder.txt文件第7行的内容 4. 输出nowcode

JAVA读取MongoDB中的二进制图片并显示在页面上

1:Jsp页面: <td><img src="${ctx}/mongoImg/show"></td> 2:xml配置: <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001

十五.各设计模式总结与对比

1.各设计模式总结与对比 1.1.课程目标 1、 简要分析GoF 23种设计模式和设计原则,做整体认知。 2、 剖析Spirng的编程思想,启发思维,为之后深入学习Spring做铺垫。 3、 了解各设计模式之间的关联,解决设计模式混淆的问题。 1.2.内容定位 1、 掌握设计模式的"道" ,而不只是"术" 2、 道可道非常道,滴水石穿非一日之功,做好长期修炼的准备。 3、 不要为了

大语言模型(LLMs)能够进行推理和规划吗?

大语言模型(LLMs),基本上是经过强化训练的 n-gram 模型,它们在网络规模的语言语料库(实际上,可以说是我们文明的知识库)上进行了训练,展现出了一种超乎预期的语言行为,引发了我们的广泛关注。从训练和操作的角度来看,LLMs 可以被认为是一种巨大的、非真实的记忆库,相当于为我们所有人提供了一个外部的系统 1(见图 1)。然而,它们表面上的多功能性让许多研究者好奇,这些模型是否也能在通常需要系

人工智能机器学习算法总结神经网络算法(前向及反向传播)

1.定义,意义和优缺点 定义: 神经网络算法是一种模仿人类大脑神经元之间连接方式的机器学习算法。通过多层神经元的组合和激活函数的非线性转换,神经网络能够学习数据的特征和模式,实现对复杂数据的建模和预测。(我们可以借助人类的神经元模型来更好的帮助我们理解该算法的本质,不过这里需要说明的是,虽然名字是神经网络,并且结构等等也是借鉴了神经网络,但其原型以及算法本质上还和生物层面的神经网络运行原理存在

Java注解详细总结

什么是注解?         Java注解是代码中的特殊标记,比如@Override、@Test等,作用是:让其他程序根据注解信息决定怎么执行该程序。         注解不光可以用在方法上,还可以用在类上、变量上、构造器上等位置。 自定义注解  现在我们自定义一个MyTest注解 public @interface MyTest{String aaa();boolean bbb()

人工和AI大语言模型成本对比 ai语音模型

这里既有AI,又有生活大道理,无数渺小的思考填满了一生。 上一专题搭建了一套GMM-HMM系统,来识别连续0123456789的英文语音。 但若不是仅针对数字,而是所有普通词汇,可能达到十几万个词,解码过程将非常复杂,识别结果组合太多,识别结果不会理想。因此只有声学模型是完全不够的,需要引入语言模型来约束识别结果。让“今天天气很好”的概率高于“今天天汽很好”的概率,得到声学模型概率高,又符合表达

SQL Server中,always on服务器的相关操作

在SQL Server中,建立了always on服务,可用于数据库的同步备份,当数据库出现问题后,always on服务会自动切换主从服务器。 例如192.168.1.10为主服务器,12为从服务器,当主服务器出现问题后,always on自动将主服务器切换为12,保证数据库正常访问。 对于always on服务器有如下操作: 1、切换主从服务器:假如需要手动切换主从服务器时(如果两个服务