Golang连接操作MongoDB基础处理

目录

    • 一、各步骤操作
      • 连接数据库
      • 插入数据
      • 查询多条数据
      • 删除数据
      • 分组查询数据
    • 二、总代码

一、各步骤操作

下面查询使用到的bson.M和bson.D差不多,只要区别在于M内部元素是无序的map,D是有序的切片

连接数据库

func connectDB(ctx context.Context) {clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")client, err := mongo.Connect(ctx, clientOptions)if err != nil {return}// 测试一下连通性if err := client.Ping(ctx, nil); err != nil {return}// 关闭defer func() { _ = client.Disconnect(ctx) }()// 获取MongoDB数据库集合对象。learn数据库,test_data集合collection := client.Database("learn").Collection("test_data")return
}

插入数据

func insertData(ctx context.Context, collection *mongo.Collection) {// 集合插入一条数据insertResult, err := collection.InsertOne(ctx, bson.M{"name": "植物大战僵尸", "age": 18, "class": "初一", "lastTime": time.Now().Format("2006-01-02 15:04:05")})if err != nil {println("插入失败", err.Error())return}println("插入数据的文档id为:", insertResult.InsertedID)
}

查询多条数据

func findData(ctx context.Context, collection *mongo.Collection, filter interface{}, opts ...*options.FindOptions) {// 查找数据,获得游标cursor, err := collection.Find(ctx, filter, opts...)if err != nil {println("查询失败", err.Error())return}// 关闭游标defer func() { _ = cursor.Close(ctx) }()for cursor.Next(ctx) {// 查询一条数据,并映射数据到 bson 格式中var result TestDataif err := cursor.Decode(&result); err != nil {println("解析数据失败", err.Error())return}fmt.Printf("找到多条数据,内容为: %+v\n", result)}
}

删除数据

func deleteOne(ctx context.Context, collection *mongo.Collection) {// 查询条件filter := bson.D{{"name", "植物大战僵尸"}, {"age", 19}}// 集合删除数据deleteResult, err := collection.DeleteMany(ctx, filter)if err != nil {println("删除失败", err.Error())return}println("删除数据的数量为:", deleteResult.DeletedCount)
}

分组查询数据

func groupData(ctx context.Context, collection *mongo.Collection) {filter := mongo.Pipeline{// 先查找age字段大于等于9bson.D{{"$match", bson.D{{"age", bson.D{{"$gte", 9}}}}}},// 对gender字段分组(_id是固定的),然后对分组下的englishScore字段求平均值作为一个字段,且取出分组下年龄最大值bson.D{{"$group", bson.M{"_id": "$gender", "英语成绩平均数": bson.M{"$avg": "$englishScore"}, "最大年龄": bson.M{"$max": "$age"}}}},}showInfoCursor, err := collection.Aggregate(ctx, filter)if err != nil {println("分组查询失败", err.Error())return}// 关闭游标defer func() { _ = showInfoCursor.Close(ctx) }()for showInfoCursor.Next(ctx) {// 查询一条数据,并映射数据到 bson 格式中var result bson.Mif err := showInfoCursor.Decode(&result); err != nil {println("解析数据失败", err.Error())return}fmt.Printf("找到多条数据,内容为: %+v\n", result)}
}

二、总代码

package mainimport ("context""fmt""go.mongodb.org/mongo-driver/bson""go.mongodb.org/mongo-driver/mongo""go.mongodb.org/mongo-driver/mongo/options""time"
)// TestData 文档数据结构
type TestData struct {Name         string    `bson:"name"`         // 姓名Age          int       `bson:"age"`          // 年龄Gender       int32     `bson:"gender"`       // 性别 1男2女LastTime     time.Time `bson:"lastTime"`     // 下课时间Class        string    `bson:"class"`        // 班级EnglishScore float32   `bson:"englishScore"` // 英语成绩
}func main() {ctx := context.TODO()// 连接MongoDBmongoClient, err := connectDB(ctx)if err != nil {println("连接失败了", err.Error())return}defer func() { _ = mongoClient.Disconnect(ctx) }()// 获取MongoDB数据库集合对象collection := mongoClient.Database("learn").Collection("test_data")// 插入数据//insertData(ctx, collection)insertSomeData(ctx, collection)// 查询数据//findOneData(ctx, collection)findSomeData(ctx, collection)// 更新字段信息//updateOne(ctx, collection)//updateSome(ctx, collection)// 删除一条文档//deleteOne(ctx, collection)// 使用各种条件语句,查询多条数据//findDataCondition(ctx, collection)// 分组查询//groupData(ctx, collection)
}// 连接数据库
func connectDB(ctx context.Context) (*mongo.Client, error) {clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")client, err := mongo.Connect(ctx, clientOptions)if err != nil {return nil, err}if err := client.Ping(ctx, nil); err != nil {return nil, err}return client, nil
}// 插入一条数据
func insertData(ctx context.Context, collection *mongo.Collection) {// 集合插入一条数据insertResult, err := collection.InsertOne(ctx, bson.M{"name": "植物大战僵尸", "age": 18, "class": "初一", "lastTime": time.Now().Format("2006-01-02 15:04:05")})if err != nil {println("插入失败", err.Error())return}println("插入数据的文档id为:", insertResult.InsertedID)
}// 插入多条数据
func insertSomeData(ctx context.Context, collection *mongo.Collection) {var data = []TestData{{Name: "张三", Age: 8, Gender: 1, LastTime: time.Date(2024, 4, 8, 3, 0, 0, 0, time.UTC), Class: "高一", EnglishScore: 60.5},{Name: "李三文", Age: 9, Gender: 2, LastTime: time.Date(2024, 4, 8, 4, 0, 0, 0, time.UTC), Class: "高三", EnglishScore: 59.7},{Name: "李三武", Age: 10, Gender: 1, LastTime: time.Date(2024, 4, 8, 5, 0, 0, 0, time.UTC), Class: "高一", EnglishScore: 86.2},{Name: "李四", Age: 11, Gender: 2, LastTime: time.Date(2024, 4, 8, 6, 0, 0, 0, time.UTC), Class: "高二", EnglishScore: 37.0},{Name: "王五", Age: 12, Gender: 1, LastTime: time.Date(2024, 4, 8, 7, 0, 0, 0, time.UTC), Class: "高一", EnglishScore: 27.8},}var insertData []interface{}for _, datum := range data {insertData = append(insertData, datum)}// 集合插入多条数据insertResult, err := collection.InsertMany(ctx, insertData)if err != nil {println("插入失败", err.Error())return}fmt.Printf("插入数据的文档id为:%+v", insertResult.InsertedIDs)
}// 查找一条数据
func findOneData(ctx context.Context, collection *mongo.Collection) {// 查询条件filter := bson.M{"name": "张三"}// 查询一条数据,并映射数据到结构体中var result TestDataif err := collection.FindOne(ctx, filter).Decode(&result); err != nil {println("查询失败", err.Error())return}fmt.Printf("找到一条数据,内容为: %+v\n", result)// name字段值为张三,获取数量countNumber, err := collection.CountDocuments(ctx, filter)if err != nil {println("查询数量失败", err.Error())return}println("数量为:", countNumber)
}// 查找数据,使用各种条件语句
// bson.M和bson.D差不多,只要区别在于bson.M内部元素是无序的
func findDataCondition(ctx context.Context, collection *mongo.Collection) {var opt *options.FindOptions// class的值为高一,且age的值大于10filter := bson.D{{"class", "高一"}, {"age", bson.D{{"$gt", 10}}}}// class的值为高一,且age的值小于9//filter := bson.D{{"class", "高一"}, {"age", bson.D{{"$lt", 10}}}}// class的值为高一,且age的值大于等于10//filter := bson.D{{"class", "高一"}, {"age", bson.D{{"$gte", 10}}}}// class的值为高一,且age的值大于等于10,同时age的值小于等于18//filter := bson.D{{"class", "高一"}, {"age", bson.D{{"$gte", 10}, {"$lte", 18}}}}// class的值为高一,且age的值不等于10//filter := bson.D{{"class", "高一"}, {"age", bson.D{{"$ne", 10}}}}// name模糊匹配以李字符开头的字符串// options:【i代表不区分大小写,s代表允许点字符匹配所有的字符包括换行符,x代表忽略所有空白字符,m代表匹配包含有换行符的场景同时允许使用锚(^开头$结尾)】//filter := bson.M{"name": bson.M{"$regex": "^李", "$options": "m"}}// name字段值为李四,且指定只返回class列//filter := bson.D{{"name", "李四"}}//opt = options.Find().SetProjection(bson.D{{"class", 1}})// gender字段值为1,且根据englishScore字段排序,值为1从小到大,值为-1从大到小//filter := bson.D{{"gender", 1}}//opt = options.Find().SetSort(bson.D{{"englishScore", -1}})// name字段值为王者,且只返回一条数据//filter := bson.D{{"gender", 1}}//opt = options.Find().SetLimit(1)// name字段值为王者,分页查询//filter := bson.D{{"gender", 1}}//opt = options.Find().SetSort(bson.D{{"englishScore", 1}}).SetSkip(1).SetLimit(1)// class字段值为高一,or条件查找age为8或者gender值为1//filter := bson.D{{"class", "高一"}, {"$or", []bson.D{bson.D{{"age", 8}}, bson.D{{"gender", 1}}}}}// name字段值为张三或者李四//filter := bson.D{{"name", bson.D{{"$in", []string{"张三", "李四"}}}}}// lastTime字段时间区间范围查询,lastTime保存在数据库的类型必须为Date//filter := bson.M{"lastTime": bson.M{//	"$gte": time.Date(2024, 4, 8, 3, 0, 0, 0, time.UTC),//	"$lte": time.Date(2024, 4, 8, 5, 0, 0, 0, time.UTC),//}}findData(ctx, collection, filter, opt)
}// 查找多行数据底层封装
func findData(ctx context.Context, collection *mongo.Collection, filter interface{}, opts ...*options.FindOptions) {// 查找数据,获得游标cursor, err := collection.Find(ctx, filter, opts...)if err != nil {println("查询失败", err.Error())return}// 关闭游标defer func() { _ = cursor.Close(ctx) }()for cursor.Next(ctx) {// 查询一条数据,并映射数据到 bson 格式中var result TestDataif err := cursor.Decode(&result); err != nil {println("解析数据失败", err.Error())return}fmt.Printf("找到多条数据,内容为: %+v\n", result)}
}// 查找多条数据
func findSomeData(ctx context.Context, collection *mongo.Collection) {findData(ctx, collection, bson.D{{"name", "王者"}})
}// 更新一条数据
func updateOne(ctx context.Context, collection *mongo.Collection) {// 查询条件filter := bson.D{{"name", "植物大战僵尸"}, {"age", 18}}// 更新的字段和值信息updateData := bson.D{{"$set", bson.D{{"class", "初二"}}}}// 集合更新一条数据updateResult, err := collection.UpdateOne(ctx, filter, updateData)if err != nil {println("更新失败", err.Error())return}println("更新数据的文档id为:", updateResult.UpsertedID, ",匹配数量:", updateResult.MatchedCount, ",修改数量:", updateResult.ModifiedCount)
}// 更新多条数据
func updateSome(ctx context.Context, collection *mongo.Collection) {// 查询条件filter := bson.D{{"name", "植物大战僵尸"}}// 更新的字段和值信息updateData := bson.D{{"$set", bson.D{{"class", "六年级"}}}}// 集合更新一条数据updateResult, err := collection.UpdateMany(ctx, filter, updateData)if err != nil {println("更新失败", err.Error())return}println("更新数据的文档id为:", updateResult.UpsertedID, ",匹配数量:", updateResult.MatchedCount, ",修改数量:", updateResult.ModifiedCount)
}// 删除数据
func deleteOne(ctx context.Context, collection *mongo.Collection) {// 查询条件filter := bson.D{{"name", "植物大战僵尸"}, {"age", 19}}// 集合删除数据deleteResult, err := collection.DeleteMany(ctx, filter)if err != nil {println("删除失败", err.Error())return}println("删除数据的数量为:", deleteResult.DeletedCount)
}// 对数据分组查询
func groupData(ctx context.Context, collection *mongo.Collection) {filter := mongo.Pipeline{// 先查找age字段大于等于9bson.D{{"$match", bson.D{{"age", bson.D{{"$gte", 9}}}}}},// 对gender字段分组(_id是固定的),然后对分组下的englishScore字段求平均值作为一个字段,且取出分组下年龄最大值bson.D{{"$group", bson.M{"_id": "$gender", "英语成绩平均数": bson.M{"$avg": "$englishScore"}, "最大年龄": bson.M{"$max": "$age"}}}},}showInfoCursor, err := collection.Aggregate(ctx, filter)if err != nil {println("分组查询失败", err.Error())return}// 关闭游标defer func() { _ = showInfoCursor.Close(ctx) }()for showInfoCursor.Next(ctx) {// 查询一条数据,并映射数据到 bson 格式中var result bson.Mif err := showInfoCursor.Decode(&result); err != nil {println("解析数据失败", err.Error())return}fmt.Printf("找到多条数据,内容为: %+v\n", result)}
}

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

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

相关文章

Linux之防火墙命令

1、查看防火墙状态 systemctl status firewalld1.1、开启防火墙 service firewalld start1.2、重启防火墙 service firewalld restart1.3、关闭防火墙 service firewalld stop2、查看防火墙规则 firewall-cmd --list-all # 查看全部信息 firewall-cmd --list-ports # …

C#版Facefusion ,换脸器和增强器

C#版Facefusion ,换脸器和增强器 目录 说明 效果 项目 调用代码 说明 Facefusion是一款最新的开源AI视频/图片换脸项目。是原来ROOP的项目的延续。项目官方介绍只有一句话,下一代换脸器和增强器。 代码实现参考 https://github.com/facefusion/f…

软件工程及开发模型

根据希赛相关视频课程汇总整理而成,个人笔记,仅供参考。 软件工程的基本要素包括方法、工具和(过程) 方法:完成软件开发的各项任务的技术方法; 工具:运用方法而提供的软件工程支撑环境&#xff…

基于STM32的RFID智能门锁系统

本文针对RFID技术,着重研究了基于单片机的智能门锁系统设计。首先,通过链接4*4按键模块与主控STM32,实现了多种模式,包括刷卡开锁、卡号权限管理、密码开锁、修改密码、显示实时时间等功能。其次,采用RC522模块与主控S…

【学习笔记十四】EWM发货流程概述及相关配置

一、EWM发货流程与ERP集成配置 1.将凭证类型从 ERP 系统映射至 EWM ERP交货单凭证类型LF映射到EWM凭证类型OUTB 2.从 ERP 系统映射项目类型至 EWM ERP交货单凭证类型+ERP交货单项目类型TAN映射到EWM项目类型是ODLV 3.定义出库交货的参数文件 ①定义外向交货处理的凭证类型OUT…

Opentelemetry——Instrumentation-Code-based

Code-based Learn the essential steps in setting up code-based instrumentation 了解设置基于代码的测量装置的基本步骤 Import the OpenTelemetry API and SDK 导入 OpenTelemetry API 和 SDK You’ll first need to import OpenTelemetry to your service code. If you…

Mamba论文笔记

Mamba论文 结合序列建模任务通俗地解释什么是状态空间模型?创新点和贡献 为什么Mamba模型擅长捕获long range dependencies? 结合序列建模任务通俗地解释什么是状态空间模型? 状态空间模型(State Space Model, SSM)是…

举个栗子!Tableau 技巧(270):用 Lookup 函数创建多 KPI 文本表

在 Tableau 中,文本表常用于呈现明细数据。但其实,数据粉如果想在同一视图中查看多个数据指标,也可以用到文本表。 如下示例,是不是很直观的就可以查看:不同区域随时间推移的数据指标情况呢? 如何在 Tablea…

vue3 pinia本地存储

vue3 pinia本地存储 1.安装pinia和本地存储插件 npm install pinia npm i pinia-plugin-persistedstate2.在main中全局配置 import { createPinia } from pinia import { createPersistedState } from pinia-plugin-persistedstateconst pinia createPinia() pinia.use(cre…

app证书在设置在哪

根据近日工业和信息化部发布的《工业和信息化部关于开展移动互联网应用程序备案工作的通知》,相信不少要进行IOS平台App备案的朋友遇到了一个问题,就是apple不提供云管理式证书的下载,也就无法获取公钥及证书SHA-1指纹。 已经上架的应用不想重…

Langchain入门到实战-第二弹

Langchain入门到实战 Langchain快速入门官网地址Langchain概述Langchain调用大模型更新计划 Langchain快速入门 官网地址 声明: 由于操作系统, 版本更新等原因, 文章所列内容不一定100%复现, 还要以官方信息为准 https://python.langchain.com/Langchain概述 LangChain是一个…

Awaited,Promise

下面是一个简单的示例&#xff0c;展示了如何使用 Awaited<T>&#xff1a; 假设有一个 getInitialState 函数&#xff0c;它返回一个 Promise&#xff0c;解析后的值是一个对象&#xff0c;结构如下&#xff1a; // app.ts export async function getInitialState(): P…

LOCK、ACC、ON、START的含义及正确使用

背景 前段时间在开发一个远程锁车的需求时&#xff0c;讨论到了电源状态的场景。由于初次进入汽车电子行业&#xff0c;对很多基础概念不清晰。当时听主机厂商的同事介绍一遍后&#xff0c;并不是很理解。于是趁着空闲&#xff0c;给自己充充电&#xff0c;也希望能够帮到有需…

ChatGPT个人专用版 SSRF漏洞复现(CVE-2024-27564)

0x01 产品简介 ChatGPT个人专用版是一种基于 OpenAI 的 GPT-3.5 、GPT-4.0语言模型的产品。它是设计用于 Web 环境中的聊天机器人,旨在为用户提供自然语言交互和智能对话的能力。PHP版调用OpenAI接口进行问答和画图,采用Stream流模式通信,一边生成一边输出。前端采用EventS…

php:实现压缩文件上传、解压、文件更名、压缩包删除功能

效果图 1.上传文件 2.压缩包文件 3.itemno1文件 4.上传到系统路径\ItemNo 5.更名后的itemno1文件(命名&#xff1a;当天日期六位随机数) 代码 <form action"<?php echo htmlspecialchars($_SERVER[PHP_SELF], ENT_QUOTES, UTF-8); ?>" method"post…

Udio——革命性的AI音乐生成软件

Udio是一款革命性的AI音乐生成软件&#xff0c;由前谷歌DeepMind的顶尖AI研究人员和工程师共同创立&#xff0c;得到著名风险投资公司a16z的支持。它旨在为音乐爱好者和专业人士提供一个全新的音乐创作和分享平台。用户可以通过文本提示来生成音乐&#xff0c;支持广泛的音乐风…

react项目规范新手教程

简介 React是一种流行的JavaScript库&#xff0c;用于构建用户界面。搭建一个React项目并不难&#xff0c;但确保项目的结构和配置正确可以帮助你更有效地开发和维护应用程序。以下是搭建React项目的一些步骤&#xff1a; 项目规范&#xff1a;项目中有一些开发规范和代码风格…

1688关键字搜索接口测试

1688关键字搜索接口测试贴 一、测试目的 本测试贴旨在测试1688平台的关键字搜索接口功能&#xff0c;确保接口能够正确响应并返回相关搜索结果。通过编写测试用例和代码&#xff0c;验证接口的稳定性、准确性和性能。 二、测试环境 操作系统&#xff1a;Windows 10编程语言…

OpenAI现已普遍提供带有视觉应用程序接口的GPT-4 Turbo

OpenAI宣布&#xff0c;其功能强大的GPT-4 Turbo with Vision模型现已通过公司的API全面推出&#xff0c;为企业和开发人员将高级语言和视觉功能集成到其应用程序中开辟了新的机会。 PS&#xff1a;使用Wildcard享受不受网络限制的API调用&#xff0c;详情查看教程 继去年 9 月…

[蓝桥杯] 纸张尺寸(C语言)

题目链接 蓝桥杯2022年第十三届省赛真题-纸张尺寸 - C语言网 题目理解 输入一行包含一个字符串表示纸张的名称&#xff0c;该名称一定是 A0、A1、A2、A3、A4、A5、A6、A7、A8、A9 之一&#xff0c;输出两行&#xff0c;每行包含一个整数&#xff0c;依次表示长边和短边的长度…