MongoDB
MongoDB
一、介绍
1 基本介绍
MongoDB是一个基于分布式文件存储的数据库,由C++编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。它是一个面向文档(document-oriented)的数据库,而不是关系型数据库。它支持的数据结构非常松散,类似json格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是它支持的查询语言非常强大,几乎可以实现类似关系数据库单表查询的绝大部分功能。
MongoDB作为一款通用型数据库,除了能够创建、读取、更新和删除数据之外,还提供了一系列不断扩展的独特功能:
索引
支持通用二级索引,允许多种快速查询,且提供唯一索引、复合索引、地理空间索引、全文索引
聚合
支持聚合管道,用户能通过简单的片段创建复杂的集合,并通过数据库自动优化
特殊的集合类型
支持存在时间有限的集合,适用于那些将在某个时刻过期的数据,如会话session。类似地,MongoDB也支持固定大小的集合,用于保存近期数据,如日志
文件存储
支持一种非常易用的协议,用于存储大文件和文件元数据。MongoDB并不具备一些在关系型数据库中很普遍的功能,如链接join和复杂的多行事务。省略这些的功能是处于架构上的考虑,或者说为了得到更好的扩展性,因为在分布式系统中这两个功能难以高效地实现
2 MongoDB和MySQL的对比
下面是MongoDB和关系型数据库MySQL对比
| MySQL术语 | MongoDB术语 |
|---|---|
| database数据库 | database数据库 |
| table表 | collection表(集合) |
| row行 | document行(文档) |
| column字段 | field字段 |
| index索引 | index索引 |
| pk主键 | pk主键(MongoDB将_id字段设置为主键) |
在数据存储上,文档是MongoDB的核心概念,即采用类似json格式的键值对进行数据存储;
在配置文件上,MongoDB采用yaml格式文件配置。
二、安装和卸载
官网:https://www.mongodb.com/
下载地址:https://www.mongodb.com/try/download/community
MongoDB有两个版本,社区版和企业版,作为学习下载和安装社区版即可。
1 windows
打开下载地址之后,选择社区版,windows平台,如图:

打开安装包,安装方式可以选择全部安装,如图:

安装时可以启动一个服务,以及日志和数据的存放路径,可以手动修改,也可以保持默认:

下面是MongoDB的可视化工具,这里不安装,后续有需要可以再安装:

点击next开始安装,等待安装完毕即可。
2 linux
推荐使用yum安装,首先配置yum源。创建/etc/yum.repos.d/mongodb-org-5.0.repo 文件,内容如下:
1 | [mongodb-org-5.0] |
安装MongoDB的最新稳定版本,使用如下命令
1 | yum install -y mongodb-org |
默认情况下,MongoDB默认使用
mongod用户运行,默认目录如下:
/var/lib/mongo数据目录/var/log/mongodb日志目录包管理器在安装过程中创建上述默认目录。所有者和组名为
mongod。
安装完成后,通过以下命令启动mongod进程,
1 | systemctl start mongod |
你可以通过以下命令来验证mongod进程是否已经成功启动:
1 | systemctl status mongod |
其他命令:
1 | systemctl enable mongod # 设置开机自启动 |
3 卸载
windows直接在控制面板卸载即可。这里介绍linux的卸载:
首先停止mongod服务
1 | service mongod stop |
删除以前安装的任何MongoDB包
1 | yum erase $(rpm -qa | grep mongodb-org) |
删除数据文件和日志文件
1 | sudo rm -r /var/log/mongodb |
三、基本使用
官方文档:https://docs.mongodb.com/
接下来的内容在CentOS7环境下完成。
1 数据类型
MongoDB的数据类型为BSON,是一种二进制序列化格式,可以认为类似于JSON。
举例:
1 | #1、null:用于表示空或不存在的字段 |
2 数据库操作
连接mongod服务:
1 | mongo --host localhost --port 27017 |
连接后,可以查看和切换数据库:
1 | > show databases # 查看数据库命令 可以简写为 show dbs |
发现和mysql的命令差不多。
使用use命令时,如果数据库不存在,MongoDB会首次存储该数据库的数据时创建该数据库。因此,可以切换到不存在的数据库并执行插入操作,并不会报错,比如:
1 | > use test |
3 集合操作
集合(表)操作
1 | #1、添加表 |
4 文档操作
切换到test库:
1 | use test |
4.1 插入文档
插入单个文档
1 | # 插入数据,下面的示例将一个新文档插入到inventory集合中。 |
插入多个文档
1 | # 下面的示例将3个新文档插入到inventory集合中。 |
MongoDB文档与Javascript的对象相近,因此可以这样:
1 | for(let i=1;i<=5;i++){ |
4.2 查询文档
查询一个表(集合)中的所有文档,可以将一个空文档作为查询过滤器参数传递给查询函数
1 | db.inventory.find({}) |
指定相等条件的查询
1 | db.inventory.find({item: "mat"}) |
除了上述的基本查询,还可以使用比较运算符,如下表所示
| 运算符 | 说明 |
|---|---|
$eq | 匹配等于指定值的值。 |
$gt | 匹配大于指定值的值。 |
$gte | 匹配大于或等于指定值的值。 |
$in | 匹配数组中指定的任何值。 |
$lt | 匹配小于指定值的值。 |
$lte | 匹配小于或等于指定值的值。 |
$ne | 匹配所有不等于指定值的值。 |
举例:
1 | # 1 查询inventory集合中status字段为A或者D或者Z |
查询时控制显示的列:
1 | db.inventory.find({status:"A"},{'_id':0,'qty':1,'name':1}) |
除了比较运算符还有很多运算符,比如逻辑运算符:
| 运算符 | 说明 |
|---|---|
$and | 返回与两个子句的条件匹配的所有文档。 |
$not | 反转查询表达式的效果并返回与查询表达式不匹配的文档。 |
$nor | 返回所有未能匹配两个子句的文档。 |
$or | 返回与任一子句的条件匹配的所有文档。 |
更多运算符请参考官方文档。
查询出的结果可以进行排序:
1 | # 排序: 1代表升序,-1代表降序 |
查询结果进行分页:
1 | # 分页: limit代表取多少个文档,skip代表跳过前多少个文档。 |
查询结果计数:
1 | # 使用count计数 |
4.3 更新文档
基本语法格式如下:
1 | db.collection.update( |
为了更新单个文档,MongoDB提供了更新操作符,例如$set,来修改字段值:
1 | db.inventory.updateOne( |
上述更新操作:
- 使用
$set运算符将字段size.uom的值更新为cm,将字段status的值更新为P - 使用
$currentDate运算符将字段的值更新为lastModified当前日期。如果lastModified字段不存在,将创建该字段。
相关的运算符如下:
| 运算符 | 说明 |
|---|---|
$currentDate | 将字段的值设置为当前日期,可以是日期或时间戳。 |
$inc | 将字段的值增加指定的数量。 |
$min | 仅当指定值小于现有字段值时才更新字段。 |
$max | 仅当指定值大于现有字段值时才更新字段。 |
$mul | 将字段的值乘以指定的数量。 |
$rename | 重命名字段。 |
$set | 设置文档中字段的值。 |
$setOnInsert | 如果更新操作导致插入文档,则设置字段的值。如果更新操作没有导致插入则什么都不做。 |
$unset | 从文档中删除指定的字段。 |
$addToSet | 仅当集合中尚不存在元素时,才将元素添加到数组中。 |
$pop | 删除数组的第一项或最后一项。 |
$pull | 删除与指定查询匹配的所有数组元素。 |
$push | 将项目添加到数组。 |
$pullAll | 从数组中删除所有匹配的值。 |
MongoDB提供以下方法来更新集合中的文档:
- db.collection.updateOne():即使匹配多个文档,也最多更新单个文档
- db.collection.updateMany():匹配多少文档就更新多少文档
- db.collection.replaceOne():即使匹配多个文档,也只替换单个文档
使用举例:
1 | # 1、$inc增加或者减少:将qty增加1 |
更多用例请参阅官方文档。
4.4 删除文档
提供两种删除方法:
db.collection.deleteMany():删除多个db.collection.deleteOne():删除一个
要从集合中删除所有文档,请将一个空的过滤器{}传递给db.collection.deleteMany()方法
1 | db.inventory.deleteMany({}) |
删除所有符合条件的文档:
1 | db.inventory.deleteMany( {'qty': 100} ) # 删除所有qty为100的文档 |
仅删除一个符合条件的文档:
1 | db.inventory.deleteOne( {'qty': 100} ) # 即使匹配多个,也只删除一个qty为100的文档 |
5 聚合
聚合操作可以处理多个文档并返回计算结果。比如:
- 将多个文档中的值组合在一起。
- 对文档中的值进行运算操作并返回结果
- 分析数据随时间的变化
要执行聚合操作,可以使用
聚合管道的每个阶段对输入文档执行一个操作。例如,一个阶段可以过滤文档、分组文档和算值。从一个阶段输出的文档将输入到下一个阶段。聚合管道可以返回文档组的结果。例如,返回总值、平均值、最大值和最小值。
创建用例:
1 | db.orders.insertMany( [ |
下面使用聚合管道,包含两个阶段并返回每个产品的紧急订单总数:
1 | db.orders.aggregate( [ |
更多相关运算符可参阅官方文档。
四、访问控制
MongoDB 使用基于角色的访问控制 (RBAC) 来管理对 MongoDB 系统的访问。用户被授予一个或多个角色,这些角色决定了用户对数据库资源和操作的访问权限。在角色分配之外,用户无权访问系统。
MongoDB默认不启用访问控制,可以使用--auth选项来开启。启用访问控制后,用户必须进行身份验证。
MongoDB的用户创建在库下,每个数据库都可以创建用户,一般来说,要管理哪个库,就在哪个库下创建账号。管理员账号建在amdin库下。
1 内置角色
介绍常用的内置角色。更多角色请参考这里。
数据库用户角色:
read读权限,提供读取所有非系统集合上的数据的能力。readWrite读写权限,包含read所有权限以及修改所有非系统集合上的数据的能力。
数据库管理角色:
dbAdmin提供执行管理任务的能力,例如与模式相关的任务、索引和收集统计信息。此角色不授予用户和角色管理权限。userAdmin提供在当前数据库上创建和修改角色和用户的能力。dbOwner数据库所有者可以对数据库执行任何管理操作。此角色结合了readWrite、dbAdmin和userAdmin的权限。
集群管理角色:
hostManager提供监视和管理服务器的能力clusterManager在集群上提供管理和监视操作。可以访问配置和本地数据库,这些数据库分别用于分片和复制clusterMonitor提供对监控工具的只读访问clusterAdmin提供最强大的集群管理访问(副本集、分片、主从等)。组合了clusterManager、clusterMonitor和hostManager角色的能力,还提供了dropDatabase操作
备份恢复角色:
backup提供备份数据所需的能力restore提供使用mongorestore恢复数据的能力
以下角色提供了为任何用户分配对任何数据库的任何特权的能力,这意味着具有这些角色之一的用户可以为自己分配对任何数据库的任何特权:
dbOwner角色作用于admin数据库时userAdmin角色作用于admin数据库时userAdminAnyDatabase角色
以下角色提供对所有资源的完全权限:
root
2 创建管理员用户
管理员用户在admin库下创建
1 | > use admin |
其他普通用户的创建也是一样的,提供一个通用模版:
1 | > db.createUser({ |
3 开启访问控制
创建完成用户后,可以通过修改配置文件来启用RBAC,或者在命令行启动MongoDB时加上 -auth参数启动。这里选择前者:
1 | vim /etc/mongod.conf # mongdb的配置文件,是yaml格式 |
补充:更多关于配置文件的内容,参阅官方文档:https://docs.mongodb.com/manual/reference/configuration-options/
重启mongod服务:
1 | systemctl restart mongod |
如果出现重启失败的情况,查看mongod状态:
systemctl status mongod如果有类似的错误
Process: ***ExecStart=/usr/bin/mongod $OPTIONS (code=exited, status=14),通常是权限问题,mongod没有对必需文件的写权限,导致数据库服务不能启动。解决方案如下:
1
2
3 chown -R mongod:mongod /var/lib/mongo
chown -R mongod:mongod /var/log/mongodb
chown mongod:mongod /tmp/*.sock
重启后,尝试连接服务:
1 | mongosh --host localhost --port 27017 |
发现不使用用户名和密码依然可以连接到数据库。但是没有权限查看数据库。
在登录时认证:
1 | mongosh --host localhost --port 27017 -u root -p 123 --authenticationDatabase admin |
也可以先不认证,连接之后再认证:
1 | mongosh --host localhost --port 27017 # 先不认证 |
4 删除用户
使用如下命令:
1 | > db.dropUser("root") |
5 修改密码
使用如下命令:
1 | db.changeUserPassword("user","new_passwd") |
五、API
MongoDB官方提供了众多API方便不同语言调用,包括C,C++,GO,Java,Python,PHP,Node.js,C#等等。
你可以点击这里查看所支持的所有库。
1 Go
https://pkg.go.dev/go.mongodb.org/mongo-driver@v1.8.0#section-readme
2 Python
https://pymongo.readthedocs.io/en/stable/tutorial.html
3 Java
https://docs.mongodb.com/drivers/java-drivers/