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

文章目录

    • 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.mfbz.cn/a/353549.html

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

相关文章

Qt项目文件以及对象树

"在哪里走散,你都会找到我~" 前篇,我们仅仅对Qt创建了第一个简单的项目。相比于使用其他IDE创建工程项目,Qt会为自动创建诸如:.pro、.h\.cpp、.iu等文件,这些文件到底是什么?我们在使用Qt时 应该…

c++ QT 信号的个人理解 信号就是独立文件调用的一种“协议”

一. 简介 就我个人来理解,信号槽机制与Windows下消息机制类似,消息机制是基于回调函数,Qt中用信号与槽来代替函数指针,使程序更安全简洁。 信号和槽机制是 Qt 的核心机制,可以让编程人员将互不相关的对象绑定在一起&a…

IntelliJ IDE 插件开发 | (五)VFS 与编辑器

系列文章 IntelliJ IDE 插件开发 |(一)快速入门IntelliJ IDE 插件开发 |(二)UI 界面与数据持久化IntelliJ IDE 插件开发 |(三)消息通知与事件监听IntelliJ IDE 插件开发 |(四)来查收…

[GYCTF2020]Ezsqli1

打开环境,下面有个提交表单 提交1,2有正确的查询结果,3以后都显示Error Occured When Fetch Result. 题目是sql,应该考察的是sql注入 简单fuzz一下 发现information_schema被过滤了,猜测是盲注了。 测试发现只要有东…

Qt : Style Sheet

When a style sheet is active, the QStyle returned by QWidget::style() is a wrapper “style sheet” style, not the platform-specific style. The wrapper style ensures that any active style sheet is respected and otherwise forwards the drawing operations to t…

Linux 系统相关的命令

目录 一. 系统用户相关1.1 查看当前访问的主机和用户1.2 切换用户1.2.1 设置root用户密码1.2.2 普通用户和root用户切换 1.4 系统状态1.4.1 vmstat 查看当前系统的状态1.4.2 history 查看系统中输入过的命令 二. 系统文件相关2.1 权限修改2.2 磁盘占用2.2.1 每秒钟监视当前磁盘…

在 VUE 项目中,使用 Axios 请求数据时,提示跨域,该怎么解决?

在 VUE 项目开发时,遇到个问题,正常设置使用 Axios 库请求数据时,报错提示跨域问题。 那在生产坏境下,该去怎么解决呢? 其可以通过以下几种方式去尝试解决: 1、设置允许跨域请求的响应头 1.1 在响应头中…

LINUX基础培训十九之常见服务nfs介绍

前言、本章学习目标 了解nfs服务用途掌握nfs服务器的配置掌握nfs客户端的配置使用 一、NFS简介 NFS(Network File System)即网络文件系统,它允许网络中的计算机之间通过TCP/IP网络共享资源。在NFS的应用中,本地NFS的客户端应用…

机器学习第一个项目-----鸢尾花数据集加载及报错解决

项目步骤 如刚开始做,从 “项目开始” 看; 如遇到问题从 “问题” 开始看; 问题 报错如下 ModuleNotFoundError: No module named sklearn解决过程 查看官网,感觉可能是python版本和skilearn版本不匹配,更新一下p…

使用vue_cli脚手架创建Vue项目(cmd和图形化方式)

使用vue_cli脚手架创建Vue项目(cmd和图形化方式) 创建项目(cmd方式) vue create vue_cli1.方向键选择manually select feature(手动选择方式创建),回车 2.按空格键选择需要的组件:Babel、PWA、Router、Vuex、CSS,回…

【GitHub项目推荐--游戏模拟器(switch)】【转载】

01 任天堂模拟器 yuzu 是 GitHub 上斩获 Star 最多的开源 Nintendo Switch 模拟器 ,使用 C 编写,考虑到了可移植性,该模拟器包括 Windows 和 Linux 端。 如果你的 PC 满足必要的硬件要求,该模拟器就能够运行大多数商业游戏&…

Django实战

一、开发登录表单 def login_form(request):html <html><body><form method"post">用户名:<input name "username" type"text"></input></br>密码&#xff1a;<input name "password" type…

破解Windows系统密码(保姆级教学)

前言: 本篇博客只是技术分享并非非法传播知识,实验内容均是在虚拟机中进行,并非真实环境 正文: 看到题目大家都已经晓得这篇博客是干嘛了,我也不废话了,直接上win7素材 需要windows10破解过程的关注后在下面评论"已关注,请私聊"我会私发给你 一.windows7电脑密码破解…

C++17中lambda表达式新增加支持的features

C17中对lambda表达式新增加了2种features&#xff1a;lambda capture of *this和constexpr lambda 1.lambda capture of *this: *this:拷贝当前对象,创建副本&#xff1a;捕获*this意味着该lambda生成的闭包将存储当前对象的一份拷贝 。 this:通过引用捕获。 当你需…

C语言-指针的基本知识(下)

四、指针的分类 按指针指向的数据的类型来分 1:字符指针 字符型数据的地址 char *p;//定义了一个字符指针变量&#xff0c;只能存放字符型数据的地址编号 char ch; p &ch; 2&#xff1a;短整型指针 short int *p;//定义了一个短整型的指针变量p&#xff0c…

[Raspberry Pi]如何利用ssh將樹莓派切換連接至陌生的wifi基地台?

當已習慣使用VNC遠端控制樹莓派後&#xff0c;原用來設定樹莓派的電腦螢幕和鍵盤也逐漸挪為它用。此次攜帶樹莓派外出&#xff0c;同時又希望使樹莓派連接當地的wifi AP&#xff0c;利用VNC遠端桌面切換新的wifi AP需要重新設定wifi密碼&#xff0c;但卻無法在VNC遠端桌面看到密…

响应式Web开发项目教程(HTML5+CSS3+Bootstrap)第2版 例5-2 JavaScript 获取HTML元素对象

代码 <!doctype html> <html> <head> <meta charset"utf-8"> <title>JavaScript 获取 HTML 元素对象</title> </head><body> <input type"text" value"admin" /> <br> <input …

代码随想录算法训练DAY29|回溯5

算法训练DAY29|回溯5 491.递增子序列 力扣题目链接 给定一个整型数组, 你的任务是找到所有该数组的递增子序列&#xff0c;递增子序列的长度至少是2。 示例: 输入: [4, 6, 7, 7] 输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]] 说…

canvas绘制旋转的大风车

查看专栏目录 canvas实例应用100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

Android Handler完全解读

一&#xff0c;概述 Handler在Android中比较基础&#xff0c;本文笔者将对此机制做一个完全解读。读者可简单参考上述类图与时序图&#xff0c;便于后续理解。 二&#xff0c;源码解读 1&#xff0c;主线程伊始 众所周知&#xff0c;通过Zygote的fork方式&#xff0c;新创建…