MongoDB简单CRUD操作(含GO中的库操作)

MongoDBCRUD操作(含GO中的库操作)

这周开始尝试做新项目,涉及到了文章的存储,查了查MongoDB在这方面用的比较多,因此对MongoDB和他在Golang中的用法进行了学习,以下是我的整理

文章目录

  • MongoDBCRUD操作(含GO中的库操作)
    • 简介
    • 安装
    • NoSQL文档数据库
    • 主要操作
      • 创建数据库
      • 查找数据
      • 插入数据
      • 查找数据
      • 更新/替换数据
      • 删除
    • 在Golang当中的操作
      • 安装
      • 连接
      • 基础
      • CRUD

简介

MongoDB官网:入口

MongoDB是一种文档数据库,它以其可扩展性和灵活性而闻名,能够满足各种查询和索引的需求。

它将数据存储在类似JSON的灵活文档中,这意味着字段可能因文档而异,并且数据结构可以随时间变化。

MongoDB的文档模型易于开发者学习和使用,同时具备处理任何规模复杂要求的能力。它是分布式的,因此高可用性、横向扩展和地理分布都是内置且易于使用的特性

MongoDB的特点包括:

  • 面向集合存储,易于存储对象类型的数据。
  • 模式自由,不需要预定义模式。
  • 支持动态查询,可以在任意属性上建立索引。
  • 支持复制和故障恢复,确保数据的安全性和可靠性。
  • 高效的二进制数据存储,包括大型对象(如视频)。
  • 自动处理碎片,支持云计算层次的扩展性。

MongoDB适用于需要高性能、易部署、易使用和存储数据方便的场景,如网站实时数据处理、缓存层、高伸缩性场景等。不适用于要求高度事务性的系统、传统的商业智能应用或复杂的跨文档级联查询。

安装

可参考这篇文章,不过多赘述:入口

NoSQL文档数据库

MongoDB中的结构是:db-collection-document

MongoDB将数据记录存储为BSON文档。BSON是JSON的二进制表现形式。文档由键值对构成

对字段名称有以下限制:

  1. 字段名称_id保留用作主键;它的值在集合中必须是唯一的,不可变的,并且可以是数组以外的任何类型。
  2. 字段名称不能包含null字符。
  3. 顶级字段名称不能以美元符号($)字符开头。否则,从MongoDB 3.6开始,服务器允许存储包含点(即.)和美元符号(即 $)的字段名称。

Untitled

使用文档的优点是:

文档(即对象)对应于许多编程语言中的内置数据类型。

嵌入式文档和数组减少了对昂贵连接的需求。

动态模式支持流畅的多态性。

主要操作

索引

即使从集合中删除所有文档,删除操作也不会删除索引。

原子性

MongoDB中的所有写操作都是单个文档级别的原子操作。

高性能

MongoDB提供高性能的数据持久化。特别是,

对嵌入式数据模型的支持减少了数据库系统上的I / O操作。

索引支持更快的查询,并且可以包含来自嵌入式文档和数组的键。

切换数据库

在shell中,db是指当前的数据库。键入db以显示当前数据库。

db

要切换数据库,请键入 use <db>。例如,要切换到 examples 数据库:

use examples

创建数据库

切换之前您无需创建数据库。当您第一次在数据库中存储数据时(例如在数据库中创建第一个集合),MongoDB会创建数据库。

mongosh> show dbs
admin   40.00 KiB
config  72.00 KiB
local   72.00 KiB
mongosh> use test
switched to db test
test> db.createCollection("test1")
{ ok: 1 }
test> show dbs
admin   40.00 KiB
config  72.00 KiB
local   72.00 KiB
test     8.00 KiB
test> db.dropDatabase()
{ ok: 1, dropped: 'test' }
test> show dbs
admin   40.00 KiB
config  72.00 KiB
local   72.00 KiB
test> use local
switched to db local

查找数据

test> db.test1.find()
[
  {
    _id: ObjectId('65f049c8c43bf33edd779a6c'),
    name: 'rx',
    age: 30,
    gpa: 3.2
  }
]

插入数据

test> db.test1.insertMany([{name:"rx2", age:30, gpa:3.2}, {name:"patrick", age:12, gpa:4.0}])
{
  acknowledged: true,
  insertedIds: {
    '0': ObjectId('65f04afec43bf33edd779a6d'),
    '1': ObjectId('65f04afec43bf33edd779a6e')
  }
}

test> db.test1.find()
[
  {
    _id: ObjectId('65f049c8c43bf33edd779a6c'),
    name: 'rx',
    age: 30,
    gpa: 3.2
  },
  {
    _id: ObjectId('65f04afec43bf33edd779a6d'),
    name: 'rx2',
    age: 30,
    gpa: 3.2
  },
  {
    _id: ObjectId('65f04afec43bf33edd779a6e'),
    name: 'patrick',
    age: 12,
    gpa: 4
  }
]
test> db.test1.insertOne({name:"Larry", age:"12", gpa:1.0, fullTime: false, registerDate: new Date()})
{
  acknowledged: true,
  insertedId: ObjectId('65f04cb0c43bf33edd779a6f')
}
test> db.test1.insertOne({name:"Larry", age:"12", gpa:1.0, fullTime: false, registerDate: new Date(), gradutionData:null, courses:["Bio", "Chem", "Math"], address:{street:"123 Fake st.", city:"Ontario", zip :"123"}})
{
  acknowledged: true,
  insertedId: ObjectId('65f04e02c43bf33edd779a70')
}
test>
test> db.test1.insertOne({name:"Larry", age:"12", gpa:1.0, fullTime: false, registerDate: new Date(), gradutionData:null, courses:["Bio", "Chem", "Math"], address:{street:"123 Fake st.", city:"Ontario", zip :"123"}})
{
  acknowledged: true,
  insertedId: ObjectId('65f04e02c43bf33edd779a70')
}

查找数据

test> db.test1.find()
[
  {
    _id: ObjectId('65f049c8c43bf33edd779a6c'),
    name: 'rx',
    age: 30,
    gpa: 3.2
  }
]

test> db.students.find({name:"rx"})

test> db.test1.find({name:"rx"})
[
  {
    _id: ObjectId('65f049c8c43bf33edd779a6c'),
    name: 'rx',
    age: 30,
    gpa: 3.2
  }
]
test> db.test1.find({}, {_id: false, name:true})
[
  { name: 'rx' },
  { name: 'rx2' },
  { name: 'patrick' },
  { name: 'Larry' },
  { name: 'Larry' }
]
test> db.test1.find({}, {name:true})
[
  { _id: ObjectId('65f049c8c43bf33edd779a6c'), name: 'rx' },
  { _id: ObjectId('65f04afec43bf33edd779a6d'), name: 'rx2' },
  { _id: ObjectId('65f04afec43bf33edd779a6e'), name: 'patrick' },
  { _id: ObjectId('65f04cb0c43bf33edd779a6f'), name: 'Larry' },
  { _id: ObjectId('65f04e02c43bf33edd779a70'), name: 'Larry' }
]

更新/替换数据

删除数据时,第一个参数是条件,第二个是更改字段,用$set,还可以自行添加其他选项

db.test.update(
   { name: "John" },
   { $set: { age: 31 } }
)

替换数据时,id不可替换,但是可以添加其他字段

db.inventory.replaceOne(
   { item: "paper" },
   { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 40 } ] }
)

删除

删除所有数据

db.inventory.deleteMany({})

删除对应状态的所有数据

db.inventory.deleteMany({ status : "A" })

删除对应状态下的第一个数据:

db.inventory.deleteOne( { status: "D" } )

在Golang当中的操作

我们以文章的CRUD为例

安装

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

连接

func init() {
	// Initialize MongoDB client
	client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI("mongodb://localhost:27017"))
	if err != nil {
		log.Fatal(err)
	}

	// Ping the primary
	if err := client.Ping(context.TODO(), nil); err != nil {
		log.Fatal(err)
	}

	// Get a handle for your collection
	collection = client.Database("article").Collection("article")
}

基础

  • bson.A:表示一个有序的BSON数组,类似于Go中的切片(slice)。
  • bson.E:表示**bson.D类型中的单个元素,通常用于构建bson.D**类型的文档。
  • bson.D:是一个有序的文档表示,它是一个切片,其中的元素按照定义的顺序排列。这在需要保持字段顺序的情况下非常有用,比如在创建索引或执行排序操作时。
  • bson.M:是一个无序的文档表示,它是一个映射(map),其中的元素顺序是不确定的。这在顺序不重要的情况下使用起来更简洁。

CRUD

type Article struct {
	ID      primitive.ObjectID `bson:"_id,omitempty"`
	Title   string             `bson:"title"`
	Content string             `bson:"content"`
	Author  string             `bson:"author"`
}

var (
	ctx        context.Context
	collection *mongo.Collection
)
...

func main() {
	router := gin.Default()

	router.POST("/articles", createArticle)
	router.GET("/articles/:id", getArticle)
	router.GET("/articles", listArticles)
	router.PUT("/articles/:id", updateArticle)
	router.DELETE("/articles/:id", deleteArticle)

	router.Run(":8080")
}

func createArticle(c *gin.Context) {
	var article Article
	if err := c.BindJSON(&article); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	// 自己创建
	// article := bson.D{{"name", "John"}, {"age", 30}, {"city", "New York"}}
	// doc := bson.D{{"name", "John"}, {"age", 30}, {"city", "New York"}, {"hobbies", bson.A{"reading", "gaming", "hiking"}}}

	result, err := collection.InsertOne(ctx, article)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusCreated, gin.H{"id": result.InsertedID})
}

func getArticle(c *gin.Context) {
	id := c.Param("id")

	objID, _ := primitive.ObjectIDFromHex(id)
	var article Article
	err := collection.FindOne(ctx, bson.M{"_id": objID}).Decode(&article)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Article not found"})
		return
	}

	c.JSON(http.StatusOK, article)
}

func listArticles(c *gin.Context) {
	// 设置投影,排除_id字段
	projection := bson.D{{"_id", 0}}
	opts := options.Find().SetProjection(projection)

	cursor, err := collection.Find(context.Background(), bson.M{}, opts)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	defer cursor.Close(context.Background())

	var articles []bson.M
	if err = cursor.All(context.Background(), &articles); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// 返回结果时不包含_id字段
	c.JSON(http.StatusOK, articles)
}

func updateArticle(c *gin.Context) {
	id := c.Param("id")

	objID, _ := primitive.ObjectIDFromHex(id)
	var article Article
	if err := c.BindJSON(&article); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	result, err := collection.UpdateOne(ctx, bson.M{"_id": objID}, bson.M{"$set": article})
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"updated": result.ModifiedCount})
}

func deleteArticle(c *gin.Context) {
	id := c.Param("id")

	objID, _ := primitive.ObjectIDFromHex(id)
	result, err := collection.DeleteOne(ctx, bson.M{"_id": objID})
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"deleted": result.DeletedCount})
}

下周更新更多操作

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IDEA中的Project工程、Module模块的概念及创建导入

1、IDEA中的层级关系&#xff1a; project(工程) - module(模块) - package(包) - class(类)/接口具体的&#xff1a; 一个project中可以创建多个module一个module中可以创建多个package一个package中可以创建多个class/接口2、Project和Module的概念&#xff1a; 在 IntelliJ …

vue3模块化引用组件和引用ts,调用ts中的接口

以简单的登录功能为例子 1.在util中创建loginValidators.ts import { ref, reactive } from vueinterface User{email: string;password: string; }export const loginUserreactive<User>({email: ,password: })interface Rules{email: {required: boolean;message: …

Html提高——HTML5 新增的语义化标签

引入&#xff1a; 以前布局&#xff0c;我们基本用 div 来做。div 对于搜索引擎来说&#xff0c;是没有语义的。 但是在html5里增加了语义化标签&#xff0c;如 <header>&#xff1a;头部标签 <nav>&#xff1a;导航标签 <article>&#xff1a;内容标签 &…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:ListItem)

用来展示列表具体item&#xff0c;必须配合List来使用。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。该组件的父组件只能是List或者ListItemGroup。 子组件 可以包含单个子组件。 接口 从API…

[江苏工匠杯]easyphp

先看源码 <?php highlight_file(__FILE__); $key1 0; $key2 0; ​ $a $_GET[a]; $b $_GET[b]; ​ if(isset($a) && intval($a) > 6000000 && strlen($a) < 3){if(isset($b) && 8b184b substr(md5($b),-6,6)){$key1 1;}else{die("…

遗传算法及基于该算法的典型问题的求解实践

说明 遗传算法是一个很有用的工具&#xff0c;它可以帮我们解决生活和科研中的诸多问题。最近在看波束形成相关内容时了解到可以用这个算法来优化阵元激励以压低旁瓣&#xff0c;于是特地了解和学习了一下这个算法&#xff0c;觉得蛮有意思的&#xff0c;于是把这两天关于该算法…

大模型训练准备工作

一、目录 1 大模型训练需要多少算力&#xff1f; 2. 大模型训练需要多少显存&#xff1f; 3. 大模型需要多少数据量训练&#xff1f; 4. 训练时间估计 5. epoch 选择经验 6. 浮点计算性能测试 二、实现 1 大模型训练需要多少算力&#xff1f; 训练总算力&#xff08;Flops&…

分割等和子集 最后一块石头的重量II 目标和

416. 分割等和子集 力扣题目链接 本题中每一个元素的数值既是重量&#xff0c;也是价值。 dp[j]表示 背包总容量&#xff08;所能装的总重量&#xff09;是j&#xff0c;放进物品后&#xff0c;背的最大重量为dp[j] 如果背包容量为target&#xff0c; dp[target]就是装满 背…

helm部署hadoop

&#xff08;作者&#xff1a;陈玓玏&#xff09; 参考helm仓库的文档&#xff1a;https://artifacthub.io/packages/helm/apache-hadoop-helm/hadoop helm helm repo add pfisterer-hadoop https://pfisterer.github.io/apache-hadoop-helm/ helm install hadoop pfistere…

机器学习 --- 模型评估、选择与验证

Java实训代码、答案&#xff0c;如果能够帮到您&#xff0c;希望可以点个赞&#xff01;&#xff01;&#xff01; 如果有问题可以csdn私聊或评论&#xff01;&#xff01;&#xff01;感谢您的支持 第1关&#xff1a;为什么要有训练集与测试集 1、下面正确的是&#xff1f;&…

升入理解计算机系统学习笔记

磁盘存储 磁盘是广为应用的保存大量数据的存储设备&#xff0c;存储数据的数量级可以达到几百到几千千兆字节&#xff0c;而基于RAM的存储器只能有几百或几千兆字节。不过&#xff0c;从磁盘上读信息的时间为毫秒级&#xff0c;比从DRAM读慢了10万倍&#xff0c;比从SRAM读慢了…

《剑指 Offer》专项突破版 - 面试题 79 ~ 84 : 详解回溯法(C++ 实现)

目录 一、回溯法的基础知识 二、集合的排列、组合 面试题 79 : 所有子集 面试题 80 : 包含 k 个元素的组合 面试题 81 : 允许重复选择元素的组合 面试题 82 : 包含重复元素集合的组合 面试题 83 : 没有重复元素集合的全排列 面试题 84 : 包含重复元素集合的全排列 一、…

wsl中安装虚拟环境virtualenv,pycharm中配置wsl解释器

wsl 中安装虚拟环境 virtualenv 注意&#xff1a; 不能将虚拟环境安装到 /root 目录下&#xff0c;在 window 文件管理中&#xff0c;没有权限访问 wsl 中的 /root 目录 安装虚拟环境 sudo pip install virtualenv sudo pip install virtualenvwrapper配置环境变量 1、创建…

基于单片机的指纹打卡机设计

摘要 在科学技术飞速发展的今天&#xff0c;社会对身份识别的要求越来越高&#xff0c;尤其是在企业管理的人员签到、工作考勤等活动中对身份识别的高效性和可靠性的需求更为迫切。而传统的个人身份识别手段&#xff0c;如钥匙、密码、IC卡等&#xff0c;由于具有可盗用、可伪…

深入理解TCP:序列号、确认号和自动ACK的艺术

深入理解TCP&#xff1a;序列号、确认号和自动ACK的艺术 在计算机网络的世界里&#xff0c;TCP&#xff08;传输控制协议&#xff09;扮演着至关重要的角色。它确保了数据在不可靠的网络环境中可靠地、按顺序地传输。TCP的设计充满智慧&#xff0c;其中序列号&#xff08;Seq&a…

续上篇 qiankun 微前端配置

上篇文章地址&#xff1a;微前端框架 qiankun 配置使用【基于 vue/react脚手架创建项目 】-CSDN博客 主应用&#xff1a; src/main.js 配置&#xff1a; import Vue from vue import App from ./App.vue import router from ./router import { registerMicroApps, start } …

Jenkins内部使用Docker

修改docker.sock文件权限 路径在&#xff1a;/var/run/docker.sock 进入/var/run目录下 修改docker.sock文件权限&#xff0c;且让其他用户也可以读写。 cd /var/run chown root:root docker.sock chmod orw docker.sock 修改数据卷映射 切换到你Jenkins的docker-compose.…

Verdaccio部署及基础使用

1. Verdaccio 简介 Verdaccio&#xff0c;是一个轻量级的 npm 私有仓库的开源解决方案。npm是一个基于http的协议&#xff0c;用来存放软件包并且维护版本和依赖&#xff0c;利用 http 提供的 url路径 来对软件包进行增删改查。所以 Verdaccio 这款软件的核心就是实现 npm协议…

淘宝商品销量数据接口,淘宝API接口

淘宝商品销量数据接口是淘宝开放平台提供的一种API接口&#xff0c;通过该接口&#xff0c;商家可以获取到淘宝平台上的商品销量数据。 淘宝商品销量数据接口可以用于获取特定商品的销量数据、特定店铺的销量数据、特定类目的销量数据等。商家可以根据自己的需求来调用该接口&…

Gitlab部署及使用

1. 简介 GitLab 是一个用于仓库管理系统的开源项目&#xff0c;使用 Git 作为代码管理工具&#xff0c;并在此基础上搭建起来的Web服务。Gitlab是目前被广泛使用的基于 git 的开源代码管理平台&#xff0c;基于Ruby on Rails构建&#xff0c;主要针对软件开发过程中产生的代码…