MongoDB 是一种开放源代码和跨平台的面向文档的 NoSQL 数据库,在构建处理大量数据的快速且可扩展的应用程序方面很受欢迎。与传统关系型数据库将数据存储在表中不同,MongoDB 使用 JSON 格式将数据存储在文档中。在 JSON 格式中,数据被格式化为键值对,其中字段名称和值由冒号分隔并封装在花括号中。
由于其灵活的模式,MongoDB 是需要构建快速、高度可扩展的应用程序以处理大量数据的开发人员的自然选择。
MongoDB 的最新版本是 v5.0。它于 2021 年 7 月 13 日发布,并附带新功能和增强功能,其中包括:
- 多云客户端加密。
- 数据库的实时重新分片。
- 具有 Windows 函数和聚簇索引的本机时间序列平台。
- 一个稳定的 API,可以在不影响代码库的情况下轻松升级到最新版本。
- Atlas Search 全文搜索解决方案。
还有更多。通过查看MongoDB 5.0 发行说明,您可以在最新版本的 MongoDB 中找到附加功能和修复的完整列表。
在本指南中,我们将重点介绍如何在 Ubuntu 20.04 上安装 MongoDB 社区版。
第 1 步:安装 MongoDB
第一步是安装安装过程中所需的先决条件包。为此,请运行以下命令。
sudo apt install -y software-properties-common gnupg apt-transport-https ca-certificates
官方 Ubuntu 存储库提供了 MongoDB 包,可以使用 APT 包管理器在一个命令中安装,如下所示:
sudo apt install -y mongodb
但是,存储库提供的 MongoDB 版本不是最新版本。在发布本指南时,Ubuntu 存储库提供的版本是 v3.6.8。同时,MongoDB提供的最新稳定版本是5.0。
要安装最新的 MongoDB 包,您需要将 MongoDB 包存储库添加到 Ubuntu 上的源列表文件中。
但首先,您需要使用 wget 命令在您的系统上导入 MongoDB 的公钥,如下所示:
wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | sudo apt-key add -
此命令生成以下输出,表明已添加公钥
输出:
OK
接下来,将 MongoDB 的 APT 存储库添加到/etc/apt/sources.list.d目录中。
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-5.0.list
该命令将mongodb-org-5.0.list文件添加到/etc/apt/sources.list.d/目录中。该文件包含以下行:
deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse
添加存储库后,重新加载本地包索引。
sudo apt update
该命令刷新本地存储库并使 Ubuntu 知道新添加的 MongoDB 存储库。
一旦完成,安装mongodb-org提供 MongoDB 的元包。
sudo apt install -y mongodb-org
安装完成后,您可以验证安装的 MongoDB 版本,如下所示:
mongod --version
该命令显示有关 MongoDB 的一些输出,包括版本和 Git 版本以及其他详细信息。
第二步:启动并启用MongoDB服务
默认情况下,MongoDB 服务在安装时处于禁用状态。您可以通过运行以下命令来验证这一点:
sudo systemctl status mongod
要启动 MongoDB 服务,请执行以下命令:
sudo systemctl start mongod
再次确认服务是否正在运行:
sudo systemctl status mongod
从上面的输出中,您可以看到 MongoDB 已启动并正在运行。此外,您可以通过启动与数据库服务器的连接并运行诊断命令来确认数据库已启动并正在运行。
显示的命令连接到数据库并显示 MongoDB 的当前版本、服务器 URL 和它正在侦听的端口。
mongo --eval 'db.runCommand({ connectionStatus: 1 })'
此外,它还返回 MongoDB 内部connectionStatus命令的值:
“ok”参数的值为 1 表示数据库服务器正在按预期运行。在第二行中,您可以看到服务器的 URL,即本地主机地址 (127.0.0.1) 和 MongoDB 正在侦听的默认端口 (27017)。
您还可以检查默认端口如下
sudo ss -pnltu | grep 27017
验证服务按预期运行后,您现在可以启用 MongoDB 以在启动时启动,如图所示。
sudo systemctl enable mongod
至此,MongoDB 已成功安装并配置为开机启动。
第 3 步:在 MongoDB 中创建数据库和用户
到目前为止,您的 MongoDB 实例应该正在运行并配置为远程访问。现在让我们换个话题,探索如何在 MongoDB 中创建数据库和用户。
要访问 MongoDB,请运行以下命令:
mongosh
在进入 MongoDB shell 之前,您将看到有关 MongoDB 的一些信息,例如 MongoDB 和 MongoDB shell 的版本以及 Mongosh 文档的 URL。
在 Mongo shell 提示符上方,您还会看到一条警告,指示尚未为数据库启用访问控制,并且对数据和配置的读写访问受到限制。显示此警告是因为尚未启用身份验证。所以不用担心,一旦启用对数据库的身份验证,此警告就会消失。
默认情况下,安装时会创建三个数据库。这些是admin、config和local。`要列出现有数据库,请运行以下命令:
> show dbs
要创建数据库,请调用use后跟数据库名称的命令。例如,要创建一个名为employees运行命令的数据库:
> use employees
要确认您当前可以使用的数据库,请运行db命令。在这种情况下,您将获得employees输出
> db
MongoDB 提供了许多用于管理数据库的 shell 方法。该db.createUser方法允许您在数据库中创建新用户。
该方法要求您定义用户的用户名和密码以及您希望授予用户的任何角色。此信息以 JSON 格式显示。
下面是如何创建一个在数据库cherry上具有读写角色的用户的语法。employees
db.createUser( { user: "cherry", pwd: "some_password", roles: [ { role: "readWrite", db: "employees" } ] } )
您可以列出使用db.getUsers()所示方法创建的用户。
db.getUsers();
或者,您可以运行以下命令:
> show users
输出:
[ { _id: 'employees.cherry', userId: UUID("lcde5d41-fbba-4c94-806e-6a3c25709f02"), user: 'cherry', db: 'employees', roles: [ { role: 'readWrite', db: 'employees' } ], mechanisms: [ 'SCRAM-SHA-1', 'SCRAM-SHA-256' ] } ]
要删除用户,请使用db.dropUser如图所示的方法。
db.dropUser("cherry", {w: "majority", wtimeout: 4000})
输出:
{ ok: 1 }
第 4 步:保护 MongoDB
在 MongoDB 中,默认情况下不启用身份验证,这意味着任何有权访问数据库服务器的用户都可以在没有任何权限的情况下查看、添加和删除数据。这是一个严重的漏洞,可能会严重破坏您的数据。鉴于此,我们将更进一步,演示如何保护 MongoDB。
第一步是创建一个管理用户,为此,首先访问 Mongo Shell。
mongosh
接下来,连接或切换到admin数据库。
> use admin
接下来,通过粘贴这些行并按键盘上的 ENTER 键来创建数据库用户。
db.createUser( { user: "AdminCherry", pwd: passwordPrompt(), roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ] } )
让我们分解这段代码。
该user: "AdminCherry"行创建了一个名为AdminCherry的管理用户。
该pwd: passwordPrompt()方法会提示您输入管理用户的密码。pwd:这是比要求您以明文形式键入密码的字段更安全的替代方法。
该roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]行指定授予管理用户的角色。admin在这里,管理用户被授予对数据库的读写权限。由于此角色是在admin数据库中定义的,因此管理用户实际上可以读取和修改集群中的所有数据库。
这是运行命令后的输出。
要退出 Mongo Shell,请运行exit命令或按CTRL + C。
有了 Admin 用户,下一步是启用身份验证。为此,请打开mongod.conf文件。
sudo nano /etc/mongod.conf
向下滚动并找到该security 部分。取消注释并添加authorization指令并将其设置为enabled.
security: authorization: enabled
请注意,该authorization参数是缩进security的,但开头没有空格。
保存更改并退出配置文件。要应用更改,请如图所示重新启动 Mongo 服务。
sudo systemctl restart mongod
此外,请务必检查服务是否按预期运行。
sudo systemctl status mongod
现在登录到 Mongo Shell。
mongosh
这一次您会发现警告已经消失。
但是,如果您尝试执行任何与数据库相关的任务(例如查看数据库),您将得到一些表明需要身份验证的输出。
> show dbs
exit要使用身份验证登录,首先,通过运行命令注销 Mongo Shell 。然后使用以下语法使用管理用户登录。
mongosh "mongodb://adminuser@mongo-ip-address:27017"
提供管理用户的密码,这一次,您之前遇到的所有身份验证警告都将消失。
从现在开始,只有管理用户才有权限查看、创建和修改数据库中的数据。
第 5 步:配置 MongoDB 以进行远程访问
默认情况下,MongoDB 设置为在安装它的同一台服务器上进行本地访问。要启用远程访问,您需要编辑 /etc/mongod.conf文件,该文件是 MongoDB 的主要配置文件。
它包含数据库存储位置、日志记录、网络和进程管理等设置。
因此,使用文本编辑器访问配置文件。
sudo nano /etc/mongod.conf
找到该network interfaces部分并注意bindIP值。
# network interfaces net: port: 27017 bindIp: 127.0.0.1
默认情况下,MongoDB 绑定到 127.0.0.1,这是环回地址接口。这意味着 MongoDB 只能接受来自安装它的同一服务器的连接。
要允许远程访问,请添加一个逗号,然后是 Mongo 服务器的 IP 地址。
bindIp: 127.0.0.1, mongo-server-ip
保存更改并退出配置文件。要应用所做的更改,请重新启动 MongoDB 服务。
sudo systemctl restart mongod
如果启用了 UFW,请运行以下命令以允许来自远程计算机的传入连接。
sudo ufw allow from remote_machine_ip to any port 27017
要使更改生效,请重新加载防火墙。
sudo ufw reload
第六步:远程访问MongoDB
有几种方法可以远程访问 MongoDB shell。您可以使用 netcat 实用程序启动到端口 27017 的 TCP 连接,这是 MongoDB 侦听的默认端口。
如果客户机上没有安装 netcat,请按如下方式安装。
sudo apt install netcat
要通过端口 27017 建立与 MongoDB 服务器的连接,请运行以下命令:
nc -zv mongodb_server_ip 27017
出现以下输出表示连接成功。
输出:
Connection to mongodb_server_ip 27017 port [tcp/*] succeeded!
或者,您可以使用 Mongo Shell 登录,如下所示。
mongosh "mongodb://username@mongo_server_ip:27017"
shell 会自动提示您输入管理员用户的密码。
?专业提示: 使用 Mongo Shell 登录选项时,请确保客户端和远程 MongoDB 服务器上的 Mongo shell 版本相同。
第 7 步:使用 MongoDB 数据库
您可以在 MongoDB 中执行很多数据库操作。例如,您可以create、和数据库retrieve中的记录。updatedelete
插入数据
要在集合中创建文档,请使用.insertOne()方法。该方法支持多种数据类型,例如字符串、整数、布尔值和数组。
在上一步中,我们创建了一个名为employees的测试数据库。我们现在将创建一个集合并添加一些文档。集合包含一个或多个文档
下面的命令创建一个名为staff的集合,并添加一个包含一些用户数据的文档,如图所示。
db.staff.insertOne({ name: "Alice", age: 25, city: "London", married: true, hobbies: ["Travelling", "Swimming", "Cooking"] })
命令成功执行后,您将获得以下输出。
输出:
{ acknowledged: true, insertedId: ObjectId("62647ff866c1f054568a11b5") }
检索数据
staff使用集合中已创建的文档,您可以检索它并使用该.find()方法过滤结果。
例如,要检索staff集合中的所有文档,请运行以下命令:
db.staff.find()
输出:
[ { _id: ObjectId("62647ff866c1f054568a11b5"), name: 'Alice', age: 25, city: 'London', married: true, hobbies: [ 'Travelling', 'Swimming', 'Cooking' ] } ]
现在让我们尝试一些雄心勃勃的事情。我们将添加更多文档并对集合运行一些查询。
db.staff.insertOne({ name: "Bob", age: 29, city: "Liverpool", married: false, hobbies: ["Hiking", "Watching movies", "Driving"] })
db.staff.insertOne({ name: "Winnie", age: 25, city: "Bristol", married: true, hobbies: ["Playing chess", "Surfing", "Painting"] })
查询已婚员工的记录,运行以下命令:
db.staff.find({ married: true })
输出仅提供已婚雇员的记录。
输出:
[ { _id: ObjectId("62647ff866c1f054568a11b5"), name: 'Alice', age: 25, city: 'London', married: true, hobbies: [ 'Travelling', 'Swimming', 'Cooking' ] }, { _id: ObjectId("626483d6b490694bc675b767"), name: 'Winnie', age: 25, city: 'Bristol', married: true, hobbies: [ 'Playing chess', 'Surfing', 'Painting' ] } ]
更新数据
要更新或修改记录,请使用.update()方法。在此示例中,我们演示了如何name将第二条记录的值从Bob更改为Robert。
db.staff.update({ name: "Bob" }, {$set: { name: "Robert" }})
显示的输出确认记录更新成功。
输出:
{ acknowledged: true, insertedId: null, matchedCount: 1, modifiedCount: 1, upsertedCount: 0 }
您现在可以查询是否可以找到与姓名Robert匹配的记录,如下所示。
db.staff.find({ name: "Robert" })
输出:
[ { _id: ObjectId("626483c8b490694bc675b766"), name: 'Robert', age: 29, city: 'Liverpool', married: false, hobbies: [ 'Hiking', 'Watching movies', 'Driving' ] } ]
删除数据
MongoDB shell 提供了两种删除记录的方法:
.deleteOne() .deleteMany()
该.deleteOne()方法用于从集合中删除单个记录或文档。
该.deleteMany()方法从集合中删除多个文档。
删除单个记录的最佳方法是使用记录的_id值。这是赋予每条记录的唯一值,优于如下所示定义单个条目,后者会导致删除带有名称的每条记录Robert。
db.staff.deleteOne({ name: "Robert"})
因此,要安全地删除Robert记录而不影响具有相同名称值的其他记录,请_id改为指定该值。
db.staff.deleteOne({ _id: ObjectId("626483c8b490694bc675b766")})
输出:
{ acknowledged: true, deletedCount: 1 }
此外,您可以根据特定条件删除文档。在这种情况下,使用.deleteMany()删除多条记录的方法。
例如,要删除员工已婚员工集合中的所有文档,请运行命令:
db.staff.deleteMany({married: true})
输出:
{ acknowledged: true, deletedCount: 1 }
要删除集合中的所有文档,请使用.deleteMany()不带任何参数的方法:
db.staff.deleteMany({})
如果您尝试查询该集合,您会注意到输出将是空白的,这清楚地表明所有文档都已被删除并且该集合现在为空。
结论
MongoDB 是一个功能强大且灵活的 NoSQL 数据库,其受欢迎程度正在稳步上升。它是构建处理大量非结构化数据的关键任务应用程序的首选数据库。