MongoDB:从容器使用到 Mongosh、Python/Node.js 数据操作

news2025/1/19 14:15:31

文章目录

    • 1. 容器与应用之间的关系介绍
    • 2. 使用 Docker 容器安装 MongoDB
    • 3. Mongosh 操作
      • 3.1 Mongosh 连接到 MongoDB
      • 3.2 基础操作与 CRUD
    • 4. Python 操作 MongoDB
    • 5. Nodejs 操作 MongoDB
    • 参考文献

1. 容器与应用之间的关系介绍

MongoDB 的安装有时候并不是那么容易的,为了简化这个步骤,比较舒适好用的方法是使用容器(Container)安装。

在讲容器之前先说一下容器的镜像(Image),镜像是容器的前置基础,是一个关于某些应用的软件包。在镜像里规定了要运行这个应用需要准备的所有内容,包括代码、运行时、库、环境变量和配置文件等。通过一个镜像可以创建和运行容器实例。(镜像如下图1)

在这里插入图片描述

容器是一套完整的应用程序环境,包括应用程序本身及其所有依赖项,如库、运行时、系统工具和设置等。通过使用容器启动应用程序,用户无需手动解决各种依赖和系统环境问题,即可实现快速启动。以 MongoDB 为例,启动该数据库只需下载相应的 MongoDB 镜像,然后使用该镜像创建容器,即可立即启动 MongoDB 服务如下图 2 所示。

在这里插入图片描述

需要注意的是,尽管 MongoDB 运行在容器中,但实际上并非完全在本地执行。以在 Linux 主机内安装 MongoDB 为例:在 Linux 环境下进行安装需要一个操作系统,因此在容器中,除了 MongoDB,还需要集成一个完整的操作系统。

整理说明即在我们的 Linux 主机(最先希望安装数据库的机器)中,有一个容器,在这个容器内有一个 Linux 的系统,在这个系统中,安装了一个 MongoDB 的服务,所谓的使用容器运行 MongoDB 就是指使用了这样一个服务。

到这里是否有个疑问——这应该算是在当前主机访问另一个主机了,那么我们要怎么访问这个 MongoDB 呢?是否应该进入到这个系统中,然后像使用别的数据库那样,打开一个 CLI 客户端,输入指令进行增删改查呢?

当然,这确实是一种访问方式。实际上我们知道就算是安装在本地的数据库,也会选择工作在一个端口中。譬如 MySQL 的 3306,Redis 的 6379,MongoDB 的是 27017。所以容器就将系统内端口与主机的端口建立了相互的映射,将容器内的一个端口映射成主机的端口,就像是上面图 2 的 PORTS 所示,此时容器的 27017 端口就是主机的 27017 端口,访问主机的 27017 端口即是访问容器的 27017 端口。

2. 使用 Docker 容器安装 MongoDB

  1. 使用以下命令安装一个 Docker,如果你还没有的话

    apt install docker.io
    

    安装完毕后可以使用以下命令验证,如正确安装会显示一个版本号

    docker --version
    
  2. 使用以下命令下载 MongoDB 镜像

    docker pull mongo
    

    下载完成后可以使用以下命令查看镜像列表

    docker images
    
  3. 使用下载好的镜像启动 MongoDB 容器

    docker run -d -p 27017:27017 --name my-mongodb mongo
    

    在上述命令中,run 是启动一个容器,-d 是指定在后台运行;-p 是在主机和容器之间创建端口映射,冒号左侧是主机端口,右侧是容器端口;--name 是为当前容器命名,mongo 是镜像名,如果有版本需求,还可以加上版本标签,如 mongo:latest,具体的镜像名称和版本号可以通过镜像列表查看。

    容器启动后的情况使用 docker ps 命令查看如下图划线部分所示:

    在这里插入图片描述

  4. 使用下面的命令在进入到容器内

    docker exec -it 8424792f4ec4 /bin/bash
    

    其中 exec 是指在容器内执行命令,-i 是使标准输入保持打开,-t 是分配一个伪终端,同时使用可以理解为交互式执行命令,并分配一个伪终端8424792f4ec4 是容器的 ID,保证唯一的情况下可以简略输入。/bin/bash 是实际使用的 Shell(Shell 可以理解为一种命令行界面),当然你也可以只输入 bash,这是一样的效果。由此可以持续性地操作容器。情况大概如下图所示,与操作 Linux 没什么不同,顺便一提得是,从 MongoDB 的 Dockerfile 中可以看到,这个 MongoDB 是在 Debian 系统之上安装的。

    在这里插入图片描述

  5. 在容器内使用如下命令,进入到 MongoDB 的 Shell 中。

    mongosh
    

    当出现下面的状态时就代表了成功进入,那之后的操作将会在下文中详细说明。

    在这里插入图片描述

  6. 如需了解更多的 Docker 命令,可以查阅此文档 https://dockerdocs.cn/reference/index.html

3. Mongosh 操作

3.1 Mongosh 连接到 MongoDB

在 2.5 中使用 mongosh 命令连接到 MongoDB 仅为使用默认参数,该命令加上一些可能使用到的参数后类似于下面这个命令:

mongosh --host localhost --port 27017

或者类似于下面这一行:

mongosh "mongodb://localhost:27017"

这在 MongoDB 中被称为连接串(Connection String),即使用一个字符串来代表所有的参数。连接串的使用常见于使用代码连接 MongoDB 的场景。

为了安全性,一般需要启用密码来登录 MongoDB。在容器中要通过 conf 来使用密码比较困难,推荐的做法是在容器启动的时候设置一些环境变量来启用密码,如下:

docker run -d -p 27017:27017 --name my-mongodb2 \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=admin123 \
-e MONGO_INITDB_DATABASE=admin \
mongo

这个命令在启动容器的时候为 Mongodb 设置了一个 ROOT 用户 admin,密码是 admin123,在指定的数据库 admin 中进行身份验证。(注意事项:在设置密码或者账号时候,尽量避免使用 “:”、“@” 等符号,以保证密码字符串会被数据库引擎正确解析。)

这个时候如果只像上文一样,Mongosh 只设置了端口号和主机名的话,是没有权限操作的,得到的结果就像下面一样:

test> show databases
MongoServerError: Command listDatabases requires authentication

使用以下的方法选择一个进行身份验证:

1. mongosh --username admin --password admin123
2. mongosh "mongodb://admin:admin123@localhost:27017"
3. mongosh --username admin --password admin123 --authenticationDatabase admin
4. mongosh "mongodb://admin:yejue123@localhost:27017/database?authSource=admin"

如果你的用户是创建在 admin 数据库以外的,需要指定在哪个数据库进行验证,并且登录后也只能看到那一个数据库。

另外,可以依次执行下列命令看到容器在启动时设置的用户:

use admin
show collections
db.system.users.find()

在这里插入图片描述

3.2 基础操作与 CRUD

以下列出一些简单的操作:

# 显示数据库
show databases

# 创建数据库/切换数据库
use databasename

# 查看内置的 role
show roles

# 在当前数据库创建一个用户
db.createUser(
	{
		user: username, 
		pwd: password, 
		roles: [{role: "readWrite", db: dbtabases name}]
	}
)

# 查看当前数据库的所有用户
db.getUsers()

# 查看所有的集合
show collections

Mongodb 是面向文档的 NoSQL 的数据库,数据通常以 BSON 格式存储,而在 Mongosh 中看到的则是以 JSON 格式显示的。MongoDB 有三种组织数据的层级:数据库、集合(Collection)、文档(Document)。他们之间的关系用一句话概括即 “在一个数据库中有若干个集合,集合内通常存放着有相似内容的文档”。如果以关系型数据库来类比,则集合相当于一个表,一个文档相当于一行记录。这个文档并非常见的“文件文档”,而是一个键值对形式的 JSON/BSON 对象。下面我们将以一些例子来引入完整的 CRUD,请读者在其中体会集合与文档的含义。

例1:假设有一个图书管理系统的数据库,里面有各种各样的图书。

  1. 创建一个数据库 “BookManagement”。use BookManagement

  2. 使用 db.createCollection() 函数来创建名为 books 的集合,执行以下命令:

    db.createCollection("books")
    

    以默认参数创建的集合没有大小限制,存储空间会自动增长。可以通过指定一些参数来限制集合大小是否自动增长,如下则设置了一个最大存储空间 100 MB、最大文档数量为 1000 的集合:

    db.createCollection("books", { capped: true, size: 100 * 1024*1024, max: 1000})
    

    可以通过 db.collection.stats() 函数看到集合的设置:

    db.books.stats()
    
  3. Insert
    向集合内插入文档(数据)的方式有两种,下面我们分别以单条插入和多条插入的方法,向 resources 插入几个文档。

    单个插入 db.collection.insertOne()

    db.books.insertOne({
    	title: "围城",
    	authors: ["钱钟书"],
    	publication_year: 1947,
    	publisher: "上海文艺出版社",
    	tags: ["小说", "讽刺文学"],
    	remainings: 10
    })
    

    批量插入 db.collection.insertMany()

    db.books.insertMany([
      {
        title: "活着",
        authors: ["余华"],
        publication_year: 1993,
        publisher: "作家出版社",
        tags: ["小说", "现实主义"],
        remainings: 5
      },
      {
        title: "红楼梦",
        authors: ["曹雪芹"],
        publication_year: 1791,
        publisher: "人民文学出版社",
        tags: ["古典小说", "传统文学"],
        remainings: 8
      },
    ])
    

    现在可以通过以下函数来查询集合中所有的文档:

    db.books.find()
    
  4. Query
    接下来将演示三种常见的查找:“=”、“in”、“AND / OR”。
    第一种,指定相等条件:查找书名为“活着”的书

    BookManagement> db.books.find({title: "活着"})
    [
      {
        _id: ObjectId('65b49ed320bf3de68d11029c'),
        title: '活着',
        ...
      }
    ]
    

    第二种,使用查询运算符 $in :查找书名在下列所给出的列表中的书籍

    BookManagement> db.books.find({title: {$in: ["活着","围城"]}})
    [
      {
        _id: ObjectId('65b49da320bf3de68d11029b'),
        title: '围城',
        ...
      },
      {
        _id: ObjectId('65b49ed320bf3de68d11029c'),
        title: '活着',
        ...
      }
    ]
    

    第二种,使用查询运算符 gte:查询剩余数量大于等于 10 的

    BookManagement> db.books.find({remainings: {$gte: 10}})
    [
      {
        _id: ObjectId('65b49da320bf3de68d11029b'),
        title: '围城',
        remainings: 10
        ...
      }
    ]
    

    更多的查询运算符请查阅此文档:https://www.mongodb.com/docs/manual/reference/operator/query/#query-selectors

    第三种,逻辑运算符 AND:查找出版年份大于 1700 年并且是小说类型的

    BookManagement> db.books.find({publication_year: {$gt: 1700}, tags: {$in: ["小说"]}})
    [
      {
        title: '围城',
        publication_year: 1947,
        tags: [ '小说', '讽刺文学' ],
        ...
      },
      {
        title: '活着',
        publication_year: 1993,
        tags: [ '小说', '现实主义' ],
        ...
      }
    ]
    

    从结果中可以看到《红楼梦》并没有被匹配到,因为红楼梦的标签里是“古典小说”,如果我们希望凡是含有“小说”的都看做是小说,加上我们的 tags 是一个列表,那么查询条件就成了这样:查找年份大于 1700 的,内部任一标签中含有“小说”字样的书。这个查询可以使用元素匹配运算符 $elemMatch 和正则运算符 $regex,对 tags 中每一个标签进行匹配查询。

    BookManagement> db.books.find({publication_year: {$gt: 1400}, tags: {$elemMatch: {$regex: "小说"}}})
    [
      {
        title: '围城',
        publication_year: 1947,
        tags: [ '小说', '讽刺文学' ],
        ...
      },
      {
        title: '活着',
        publication_year: 1993,
        tags: [ '小说', '现实主义' ],
        ...
      },
      {
        title: '红楼梦',
        publication_year: 1791,
        tags: [ '古典小说', '传统文学' ],
        ...
      }
    ]
    
    

    第三种,逻辑运算符 OR:查找出版年份大于 1990 或者剩余数量大于等于 10 的

    BookManagement> db.books.find({$or: [{publication_year: {$gt: 1990}}, {remainings: {$gte: 10}}]})
    

(未完待续)

4. Python 操作 MongoDB

5. Nodejs 操作 MongoDB

参考文献

https://www.mongodb.com/docs/manual/
https://www.mongodb.com/docs/mongodb-shell/crud/

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

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

相关文章

C++:模板特化 非类型模板参数

目录 1.非类型模板参数 2.模板特化 2.1 为什么需要模板特化 2.2 函数模板特化 2.3 类模板特化 1.全特化 2.偏特化 1.部分特化 2.参数更进一步的限制 1.非类型模板参数 模板参数分类类型形参与非类型形参 类型形参即:出现在模板参数列表中,跟在 cl…

java正则校验,手机号,邮箱,日期格式,时间格式,数字金额两位小数

java正则校验,手机号,邮箱,日期格式,时间格式,数字金额两位小数 3.58是否为金额:true 3.582是否为金额:false 1284789qq.com是否为email:true 1284789qq.com是否为email&#xff1…

01_Anaconda环境搭建

概述 Anaconda包含了许多常用的科学计算和数据分析的库和工具。通过Anaconda,用户可以更方便地安装、管理和更新这些库和工具,从而提高工作效率。 Anaconda还提供了一个名为conda的包管理器,可以帮助用户方便地安装、管理和更新这些库和工具…

linux 基于科大讯飞的文字转语音使用

官方文档地址:离线语音合成 Linux SDK 文档 | 讯飞开放平台文档中心 一、SDK下载 1、点击上面官方文档地址的链接,可以跳转到以下界面。 2、点击“普通版”,跳转到以下界面。 3、点击“下载”跳转到以下界面 4、最后,点击“SDK下…

AI编译器的前端优化策略

背景 工作领域是AI芯片工具链相关,很多相关知识的概念都是跟着项目成长建立起来,但是比较整个技术体系在脑海中都不太系统,比如项目参与中涉及到了很多AI编译器开发相关内容,东西比较零碎,工作中也没有太多时间去做复盘…

Linux 增加 SWAP 空间

一、需求 通过阿里云启动项目时,使用Vuepress build编译静态页面时内存需要800MB,导致内存不够,因此考虑使用swap方式,置换一些内存资源存放swap磁盘。 [rootxxx myblog]# npm run docs:dev> myblog1.0.0 docs:dev > vuep…

分类预测 | Matlab实现DT决策树多特征分类预测

分类预测 | Matlab实现DT决策树多特征分类预测 目录 分类预测 | Matlab实现DT决策树多特征分类预测分类效果基本描述程序设计参考资料分类效果

ParaView更改RenderView背景颜色

如下图,这种蓝紫色是ParaView的RenderView默认设置颜色 想要更改背景颜色,需要打开Properties如果想要更改渲染物体的颜色,需要打开Color Map Editor 打开方式: 在页面上方工具栏的地方右键,勾选Properties和Color …

stable diffusion学习笔记——文生图(二)

LORA和Embeddings都可以对画面内容进行调整。目前LORA主要用来定义画面特征,如具体的人物,衣物,画风等。Embeddings目前主要用于反面提示词中,用来避免错误的画面表现。 LORA lora的全称为:低秩适应模型。lora的基本…

算法,不再难学!揭秘两款让你迅速学会算法的在线工具

1. VisuAlgo VisuAlgo 是一个由 Dr. Steven Halim 创立的在线平台,用于通过可视化的方式帮助学生和开发者理解和掌握各种复杂的数据结构和算法。该网站特别适合那些视觉学习者,也就是通过看图形、动画和演示来更好地理解概念的人。 以下是 VisuAlgo 的一些关键特点和功能: …

深兰科技入选亿欧《“制”敬不凡先锋榜·智能机器人Top10》榜单

日前,由亿欧协办的2023工博会工业智能化发展高峰论坛于上海成功举办,会上发布了《2023智能制造:“制”敬不凡先锋者》系列名单。深兰科技凭借在智能机器人开发中的技术创新和模式应用,入选《“制”敬不凡先锋榜——智能机器人Top1…

Java8-Stream 流基本应用-groupBy进行分组

groupBy进行分组 Testpublic void testStreamGroupBy(){List<UserInfoModel> resultnew ArrayList<>();for (int i 0; i < 10; i) {UserInfoModel usernew UserInfoModel();user.setUserId(i"");user.setUserName("kangshihang");result.a…

基于深度学习的狗狗类别检测

探索狗狗识别技术 引言1. 数据集介绍1.1 语境1.2 内容1.3 致谢 2. 项目背景与意义3. 项目实现流程3.1 数据处理与准备3.2 环境准备与工具安装3.3 模型配置与训练3.4 模型评估与预测3.5 模型推理与部署 4. 总结 服务 引言 随着人工智能技术的不断发展&#xff0c;图像识别已成为…

LabVIEW信号时间间隔测量

用LabVIEW软件平台开发一个用于测量两路信号时间间隔的系统。系统利用LabVIEW的数据采集和处理能力&#xff0c;能够准确测量并分析来自不同硬件板卡的信号时间间隔&#xff0c;这对于精确控制和数据分析至关重要。 系统主要由以下几部分组成&#xff1a;数据采集卡、信号处理…

【Linux】命名管道

文章目录 命名管道一、命名管道的原理二、命名管道的创建命令行中创建程序中创建 - mkfifo函数&#xff1a; 三、命名管道的使用命名管道实现server&client通信 四、匿名管道与命名管道的区别 命名管道 如果涉及到在文件系统中创建一个有名的管道&#xff0c;那么就是在使…

【c语言】详解操作符(下)

前言&#xff1a; 在上文中&#xff0c;我们已经学习了 原码、反码、补码、移位 操作符、移位操作符、位操作符、逗号表达式、下标访问[ ]、函数调用&#xff08; &#xff09;&#xff0c;接下来我们将继续学习剩下的操作符。 1. 结构成员访问操作符 1.1 结构体成员的直接访…

技术书评和笔记【01】脑机接口-电路与系统 【2020版】

前言: 荷兰作者,Amir Zjajo博士,毕业于荷兰代尔夫特理工大学,方向 面向移动健康的低功耗混合型号电路与系统,以及,面向认知的神经形态电路。 ,脑机接口 - 电路与系统一书,系统介绍了,脑机接口电路与系统的实现技术,尤其,提到了量产和设计的问题,难能可贵,摘录如…

预训练语言模型transformer

预训练语言模型的学习方法有三类&#xff1a;自编码&#xff08;auto-encode, AE)、自回归&#xff08;auto regressive, AR&#xff09;&#xff0c;Encoder-Decoder结构。 决定PTM模型表现的真正原因主要有以下几点&#xff1a; 更高质量、更多数量的预训练数据增加模型容量…

CSS--Emmet 语法

Emmet语法的前身是Zen coding,它使用缩写,来提高html/css的编写速度, Vscode内部已经集成该语法. 目录 1. 快速生成HTML结构语法 1.1 快速生成HTML结构语法 2. 快速生成CSS样式语法 2.1 快速生成CSS样式语法 1. 快速生成HTML结构语法 1.1 快速生成HTML结构语法 1. 生成标…

【C++】C++ 入门 — 命名空间,输入输出,函数新特性

C 1 前言2 命名空间2.1 概念引入2.2 开始使用2.3 投入应用 3 输入与输出3.1 基础知识3.2 开始使用3.3 注意局限 4 函数新特性4.1 缺省参数4.1.1 开始使用4.1.2 注意事项 4.2 函数重载4.2.1 开始使用4.2.2 如何实现 Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读下…