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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/31727.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode---402周赛

题目列表 3184. 构成整天的下标对数目 I 3185. 构成整天的下标对数目 II 3186. 施咒的最大总伤害 3187. 数组中的峰值 一、构成整天的下标对数目 I & II 可以直接二重for循环暴力遍历出所有的下标对,然后统计符合条件的下标对数目返回。代码如下 class So…

概率论与数理统计期末复习

概率论常考知识点汇总 总括 1. 基础概率论 概率定义:理解概率是事件发生的可能性度量,范围从0(不可能)到1(必然发生)。概率公理:掌握概率的三大公理,即非负性、规范性和可加性。条…

深入理解 Nginx 的正向代理和反向代理

在线工具站 推荐一个程序员在线工具站:程序员常用工具(http://cxytools.com),有时间戳、JSON格式化、文本对比、HASH生成、UUID生成等常用工具,效率加倍嘎嘎好用。 程序员资料站 推荐一个程序员编程资料站:…

专利的黑白图片处理:

1,本来是彩色图片,首先就是使用滤镜处理成黑白的 2,插入word中的时候,直接讲图片的背景色设置成和word一样的颜色 如何在word文档里插入图片,让插入图片的背景颜色变成和word文档背景相同的白色?...急求啊…

HTML静态网页成品作业(HTML+CSS)——美食火锅介绍网页(1个页面)

🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTMLCSS,未使用Javacsript代码,共有1个页面。 二、作品演示 三、代…

微信对话生成器2.0版本

微信对话生成器2.0版,这是一款革命性的通讯辅助工具,在数字通信领域带来了新的创新浪潮。这一升级版的生成器不仅囊括了从基本的文字编辑、格式调整到语音转换的多种功能,更重要的是,它提供了模拟真实对话的能力,使得用…

使用 git 遇到权限错误,重新生成SSH密钥

如果在执行 git 相关的命令的时候遇到权限错误,可能是因为你之前使用了不同的用户名在本地生成了SSH密钥。你可以尝试以下步骤来解决这个问题: 打开终端,并执行以下命令来删除旧的SSH密钥文件: rm ~/.ssh/id_rsa rm ~/.ssh/id_rsa…

容器之对齐构件

代码&#xff1a; #include <gtk-2.0/gtk/gtk.h> #include <glib-2.0/glib.h> #include <gtk-2.0/gdk/gdkkeysyms.h> #include <stdio.h>int main(int argc, char *argv[]) {gtk_init(&argc, &argv);GtkWidget *window;window gtk_window_ne…

C++ 72 之 友元和类模版

#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; #include <string>// 写法2&#xff1a; // template<class T1, class T2> // class Students12;// 要提前用到Students12&#xff0c;需要在前面先让编译器见过Students12才可…

汇聚荣做拼多多运营口碑怎么样?

拼多多作为国内领先的电商平台&#xff0c;其运营口碑一直是业界和消费者关注的焦点。汇聚荣作为拼多多的运营服务商&#xff0c;其服务质量直接影响到拼多多平台的用户体验和品牌形象。那么&#xff0c;汇聚荣做拼多多运营口碑怎么样呢? 一、服务响应速度 汇聚荣在服务响应速…

树莓派4B学习笔记11:PC端网线SSH连接树莓派_网线连接请求超时问题解决

今日继续学习树莓派4B 4G&#xff1a;&#xff08;Raspberry Pi&#xff0c;简称RPi或RasPi&#xff09; 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: Opencv 版本是4.5.1&#xff1a; 今日学习使用网线连接树莓派&#xff0c;网线可以提供更…

vos3000外呼系统通话会话超时中断详解

在VOS3000中&#xff0c;通话会话超时中断可能由多种因素引起。这些因素包括网络问题、配置错误、硬件资源不足等。以下是一些可能导致通话会话超时中断的详细解释&#xff1a; 网络问题&#xff1a; 网络延迟和丢包&#xff1a;网络延迟或丢包会导致数据包在传输过程中被丢弃或…

邮件推送服务商有哪些核心功能?怎么选择?

邮件推送服务商支持哪些营销工具&#xff1f;推送性能如何评估&#xff1f; 邮件推送服务商的核心功能可以帮助企业更高效地管理和优化其电子邮件营销活动&#xff0c;从而提升客户参与度和转化率。AokSend将详细介绍邮件推送服务商的一些核心功能。 邮件推送服务商&#xff…

弹窗‘xlive.dll没有被指定在Windows’要怎么解决?教你4种修复xlive.dll的方法

大家在使用电脑期间是否曾遭遇过一个弹窗警告&#xff0c;“xlive.dll没有被指定在Windows”&#xff1f;假如你确实碰到过这样的问题&#xff0c;当时你是如何应对xlive.dll文件缺失的状况呢&#xff1f;对于那些还不清楚如何处理此问题的朋友们&#xff0c;接下来所述的几种方…

Go单测时的Parallel

在 Go 语言中&#xff0c;t.Parallel() 通常用于测试代码中&#xff0c;表示将当前的测试用例标记为可以并行执行。 当在测试函数中调用 t.Parallel() 后&#xff0c;测试框架会尝试在多个 goroutine 中并行地执行被标记的测试用例。 这可以显著提高测试的执行效率&#xff0c;…

用Python的Pygame包实现水果忍者小游戏

先上一下运行结果 长按鼠标左键出刀, 切割水果几分, 切割炸弹结束游戏, 漏掉的水果也会几分, 难度会随时间慢慢提高(水果的刷新频率变快) 初始化 帧率200帧/秒, 游戏窗口大小800600 # 游戏设置 pygame.init() FPS 200 fpsClock pygame.time.Clock() WIDTH, HEIGHT 800, 60…

比官方镜像体积还小的基于Anolis OS8.6的Python3.8.8的编译安装Dockerfile

本次编译安装解决了安装3.8.8编译安装过程中的所有报错&#xff0c;同时&#xff0c;OpenSSL升级至3.0.14、内置Git&#xff0c;支持IPv6&#xff0c;Python环境同时预安装httpx和boto3模块。 FROM openanolis/anolisos:8.6 as PYTHONARG PYTHON_VERSION"3.8.8" ARG…

Elasticsearch term 查询:精确值搜索

一、引言 Elasticsearch 是一个功能强大的搜索引擎&#xff0c;它支持全文搜索、结构化搜索等多种搜索方式。在结构化搜索中&#xff0c;term 查询是一种常用的查询方式&#xff0c;用于在索引中查找与指定值完全匹配的文档。本文将详细介绍 term 查询的工作原理、使用场景以及…

【FPGA】静态分析与时序约束(持续更新

Reference&#xff1a; V2静态时序分析与时序约束文档 入门 无时序约束场景中&#xff0c;普通图像显示不清晰&#xff0c;千兆网口接收Ethernet package 数据不正常&#xff0c;红外场景中图像显示不正常 Definition&#xff1a; 我们提出一些特定的时序要求&#xff08;或…

辅助构造函数相关学习以及php实现

https://mp.weixin.qq.com/s/J9hgLTxYi7ZJdFVG2VszQg 对这个文章进行摘要生成 ### 总体概要 文章阐述了在对象创建过程中&#xff0c;辅助构造函数&#xff08;或称为“多个”构造函数&#xff09;的重要性&#xff0c;它们为代码增加了功能性逻辑&#xff0c;并允许根据需求调…