MongoDB系列教程-第一章:MongoDB简介、安装 、概念解析、用户管理、连接、实际应用示例

发布于:2025-07-30 ⋅ 阅读:(21) ⋅ 点赞:(0)

📖 第一章:MongoDB简介、安装 、概念解析、用户管理、连接、实际应用示例

文章目录

1.1 MongoDB简介

MongoDB 是一个文档型数据库,数据以 BSON 格式存储,结构类似 JSON 对象。

核心概念:

  • 数据库(Database):数据存储容器
  • 集合(Collection):数据库中的数据集合,相当于关系型数据库的表
  • 文档(Document):集合中的单条记录,由键值对组成,相当于关系型数据库的行

核心概念对比

关系型数据库    →    MongoDB
数据库(Database) →    数据库(Database)  
表(Table)       →    集合(Collection)
行(Row)         →    文档(Document)
列(Column)      →    字段(Field)

数据存储特性:文档结构灵活,字段值可包含其他文档、数组或文档数组。支持嵌套结构,无需预定义模式。(MongoDB就像一个超级灵活的电子档案柜。传统的关系型数据库(如MySQL)就像严格的表格,每一行都必须有相同的列。而MongoDB更像是一个可以存放各种形状文件夹的柜子,每个文件夹里的内容可以完全不同。)

查询与索引:

  • 支持为任意字段创建索引,提升查询和排序性能
  • 使用 JSON 格式查询语法,支持复杂查询表达式
  • 支持对嵌套对象和数组的查询操作

扩展性:

  • 数据副本:通过本地或网络创建数据镜像,实现冗余备份
  • 水平扩展:使用分片技术将数据分布到多个节点,应对负载增长

数据操作:

  • 使用 update() 命令进行文档替换或字段更新
  • MapReduce 功能处理大规模数据聚合,使用 JavaScript 编写 Map 和 Reduce 函数
  • GridFS 存储超过 BSON 限制的大文件(如图片、视频)

开发支持:

  • 服务端可执行 JavaScript 脚本
  • 支持多种编程语言:Ruby、Python、Java、C++、PHP、C#
  • 安装部署简单

MongoDB优势总结

  1. 灵活的数据结构:不需要预定义表结构
  2. JSON格式存储:天然支持复杂的嵌套数据
  3. 水平扩展:容易分布式部署
  4. 强大的查询能力:支持复杂的聚合操作

1.2 Mongo安装

1.2.1 MongoDB-Windows安装

从 MongoDB 官网下载安装,MongoDB 预编译二进制包下载地址:https://www.mongodb.com/try/download/community

在这里插入图片描述

下载 .msi 文件,下载后双击该文件,按操作提示安装即可。

安装过程:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
点击Next,默认勾选MongoDB Compass,MongoDB Compass是MongoDB官方推出的图形化用户界面(GUI)工具,专为简化MongoDB数据库的管理、查询和分析而设计。它提供了直观的可视化界面,用户无需编写复杂的命令行代码,就能轻松完成数据库连接、集合(Collection)浏览、文档(Document)增删改查、索引管理、数据导入导出等操作。同时,它还具备实时性能监控、查询性能分析等功能,帮助开发者和数据库管理员更高效地调试和优化MongoDB数据库,尤其适合初学者快速上手MongoDB,或用于日常开发中的数据管理工作。我这里直接默认安装。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
至此,安装完成,安装成功后可以在任务管理器服务里看的MongoDB服务:

在这里插入图片描述

或者直接在浏览器中输入:
在这里插入图片描述

1.2.2 MongoDB-Linux安装

参考菜鸟教程:Linux MongoDB

1.2.3 MongoDB-Mac安装

参考菜鸟教程:OSX MongoDB

1.3 MongoDB Shell安装

MongoDB Shell(简称 mongosh)是 MongoDB 官方提供的交互式命令行工具,用于通过命令与 MongoDB 数据库直接交互,支持运行查询、管理数据、执行脚本等操作。它替代了旧版的 mongo 工具,提供更完善的语法高亮、自动补全、错误提示等功能,同时支持 JavaScript 语法和 MongoDB 扩展命令,是开发者在终端环境下操作 MongoDB 的核心工具,常用于数据库调试、数据查询、脚本执行等场景。

安装比较简单,可以参考菜鸟教程的 MongoDB Shell安装,只不过也是分Windows、Linux和Mac系统,我这里是Windows下安装,具体过程如下:

访问官方地址:https://www.mongodb.com/try/download/shell,选择适合 Windows 的 MongoDB Shell 版本,我这选的msi格式(zip的其实解压出来就是msi双击安装完的样子,只不过mongosh.exe是放在了bin文件夹中,因此,选择下载哪种格式都一样),下载后双击安装程序,可以更换安装目录。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

来到 MongoDB Shell安装目录中,双击其中的mongosh.exe,会显示Please enter a MongoDB connection string (Default: mongodb://localhost/):的字样。

在这里插入图片描述
在这里插入图片描述
意在让你输入连接 MongoDB 数据库的连接字符串(如默认的 mongodb://localhost/ 就是连接本地 MongoDB 的字符串,保持默认可以直接回车),这里输入的字符串会被优先解析为完整的连接字符串(用于指定服务器地址、端口等连接信息),而非单纯的服务器名或数据库名。连接字符串的格式通常是 mongodb://<host>:<port>/<database>,其中:

  • <host>:<port> 用于指定服务器地址和端口(如 localhost:27017);
  • 末尾的 可选,用于指定连接后默认进入的数据库(若不指定,默认进入 test 数据库)。
    在这里插入图片描述
    如果输入的是非标准连接字符串的普通字符串(如随便输入 abc),mongosh 会尝试按以下规则解析:
  1. 先假设这是一个简化的连接字符串,默认补充服务器地址为 localhost:27017,形成 mongodb://localhost:27017/abc
  2. 此时,localhost:27017 是服务器地址,abc 被当作连接后默认进入的数据库名(若不存在则临时创建)。

简言之:输入的字符串主要用于补充连接信息中的 “默认数据库名”,而服务器地址会默认使用 localhost:27017(除非字符串中明确包含服务器地址,如mongodb://192.168.1.1:27017/mydb)。

这是手动双击启动mongosh.exe的连接。

实际中,安装好了MongoDB Shell了,可以直接命令中输入mongosh,如果 MongoDB 服务器运行在本地默认端口(27017),则可以直接连接。简单说,mongosh 就像一个 “开关”—— 在命令行中输入它,会直接启动 MongoDB 官方的交互式命令行工具,让你进入可以操作 MongoDB 数据库的环境。这里说的进入环境指的是:关联一个默认数据库,即输入了mongosh连接成功后,会自动进入名为 test 的默认数据库(如果该数据库不存在,会在首次操作时自动创建)。

如果你的 MongoDB 服务器是默认配置(运行在本地、端口 27017),输入 mongosh 后会自动连接到本地默认数据库test,直接进入操作界面(可以输入查询、创建集合等命令);如果需要连接其他服务器或非默认端口,就用 mongosh --host <地址>:<端口> 这种形式,本质还是通过 mongosh 指令启动工具,再附加连接参数。

  • 其中 <hostname> 是 MongoDB 服务器的主机名或 IP 地址
  • <port> 是 MongoDB 服务器的端口号

查看版本的话,命令行可以直接输入mongosh --version来查看。
在这里插入图片描述

进入数据库后,可以执行各种 MongoDB 数据库操作(这些操作后面会详细讲述):

  • 查看当前数据库:db
  • 显示数据库列表:show dbs
  • 切换到指定数据库:use <database_name>
  • 执行查询操作:db.<collection_name>.find()
  • 插入文档:db.<collection_name>.insertOne({ ... })
  • 更新文档:db.<collection_name>.updateOne({ ... })
  • 删除文档:db.<collection_name>.deleteOne({ ... })
  • 退出 MongoDB Shell:quit() 或者 exit

1.4 MongoDB概念解析

1.4.1 基础概念

MongoDB是一个文档型数据库,和传统的关系型数据库(如MySQL)有很大不同。关系型数据库就像整齐的表格,而MongoDB更像灵活的文件夹。

核心概念对比:

关系型数据库 MongoDB 简单理解
数据库(database) 数据库(database) 存放数据的容器
表(table) 数据库表/集合(Collection) 存放同类数据的容器
行(row) 数据记录行/文档(Document) 一条具体的数据记录
列(column) 数据字段/域(Field) 数据的属性
索引(index) 索引(index) 索引
主键(primary key) _id字段 每条数据的唯一标识

在MongoDB中基本的概念是:文档集合数据库,下面我们挨个介绍。

  • 文档(Document):MongoDB 的基本数据单元,通常是一个 JSON-like 的结构,可以包含多种数据类型。

  • 集合(Collection):类似于关系型数据库中的表,集合是一组文档的容器。在 MongoDB 中,一个集合中的文档不需要有一个固定的模式。

  • 数据库(Database):包含一个或多个集合的 MongoDB 实例

其它比较重要的概念:

  • BSON:Binary JSON 的缩写,是 MongoDB 用来存储和传输文档的二进制形式的 JSON。
  • 索引(Index):用于优化查询性能的数据结构,可以基于集合中的一个或多个字段创建索引。
  • GridFS:用于存储和检索大于 BSON 文档大小限制的文件的规范。
  • ObjectId:MongoDB 为每个文档自动生成的唯一标识符。
  • CRUD 操作:创建(Create)、读取(Read)、更新(Update)、删除(Delete)操作。
  • 操作符(Operators):用于查询和更新文档的特殊字段。
  • 连接(Join):MongoDB 允许在查询中使用 $lookup 操作符来实现类似 SQL 的连接操作。
  • TTL(Time-To-Live):可以为集合中的某些字段设置 TTL,以自动删除旧数据。

1.4.2 数据库

一个 MongoDB 中可以建立多个数据库。
如果在操作时没有指定数据库,MongoDB 会使用一个名为 test 的默认数据库,该数据库存储在 data 目录中。
MongoDB 的单个实例可以容纳多个独立的数据库,每一个都有自己的集合和权限,不同的数据库也放置在不同的文件中。

这里说的 “单个实例” 指的是一个正在运行的 MongoDB 服务器进程(mongod 进程)。
简单说,当你通过 mongod 命令启动 MongoDB 服务后,会在操作系统中生成一个独立的进程,这个进程就是 “单个实例”。它可以管理多个相互独立的数据库(比如一个存储用户数据的 user_db、一个存储日志的 log_db 等),每个数据库有自己的集合、文档和权限设置,且物理上存储在不同的文件中(默认位于 MongoDB 数据目录的子文件夹中,每个数据库对应一个子文件夹)。
这个设计的好处是:通过一个服务器进程即可管理多个数据库,无需为每个数据库单独启动进程,既节省系统资源,又便于集中管理。

PS:关于mongod命令放在本章最后进行讲解。

MongoDB可以同时运行多个数据库,每个数据库都是独立的。

// 查看所有数据库
> show dbs
admin   0.000GB
local   0.000GB
test    0.000GB

// 查看当前使用的数据库
> db
test

// 切换到指定数据库
> use mydatabase
switched to db mydatabase

数据库命名规则:

  • 不能为空字符串
  • 不能包含空格、点号、美元符号、斜杠、反斜杠
  • 全部小写
  • 最多64个字符

特殊数据库:

  • admin:管理员数据库,拥有所有权限
  • local:本地数据库,不会被复制
  • config:分片配置数据库

特殊数据库的详细介绍:

  1. admin 数据库:这是MongoDB的"超级管理员"数据库,相当于系统的root用户。在这里创建的用户自动获得所有数据库的管理权限,可以执行关键的服务器管理命令如关闭服务器、列出所有数据库等。它包含重要的系统集合,在生产环境中只允许数据库管理员访问。
  2. local 数据库:这是一个特殊的本地数据库,其数据永远不会被复制到其他服务器。它适合存储本地服务器特有的数据,如本地日志、临时数据、服务器配置等。在副本集环境中特别有用,因为每个节点可以存储自己特有的信息,不会影响副本集同步性能。
  3. config 数据库这是分片集群架构的核心组件,专门存储分片集群的元数据和配置信息。它包含多个重要集合,记录分片服务器信息、数据库配置、分片键信息、数据块分布等。整个分片集群的所有组件都需要访问它来获取配置信息,因此其高可用性对整个集群至关重要。

1.4.3 文档(Document) - 数据的核心

文档是MongoDB的基本数据单元,本质上是JSON格式的数据。每个文档可以有不同的结构,这是MongoDB最大的特点。
例如下图中的两个文档:
在这里插入图片描述
下表列出了 RDBMS 与 MongoDB 对应的术语:

RDBMS MongoDB
数据库 数据库
表格 集合
文档
字段
表联合 嵌入文档
主键 主键 (MongoDB 提供了 key 为 _id )
// 简单的文档
{"name": "张三", "age": 25}

// 复杂的文档
{
  "name": "李四",
  "age": 30,
  "email": "lisi@example.com",
  "address": {
    "city": "北京",
    "street": "中关村大街"
  },
  "hobbies": ["读书", "游泳", "编程"],
  "created_at": new Date()
}

文档的特点:

  • 字段名(键)是字符串
  • 字段值可以是任何类型(字符串、数字、布尔值、数组、对象等、甚至可以是整个嵌入的文档)
  • 文档中的键/值对是有序的。
  • 不能有重复的字段名(键)
  • 区分大小写

文档键命名规范:

  • 键不能含有\0 (空字符)。这个字符用来表示键的结尾。
  • .$有特别的意义,只有在特定环境下才能使用。
  • 以下划线_开头的键是保留的(不是严格要求的)。

1.4.4 集合(Collection) - 文档的容器

集合就像文件夹(文档组),存放相关的文档。一个数据库可以有多个集合。
集合(Collection)是文档(Document)的容器,类似于关系型数据库中的 “表”,但它的核心特点是无固定结构—— 这意味着你可以往同一个集合里插入格式、字段完全不同的文档,不需要提前定义 “表结构”。不过实际使用中,集合里的文档通常会有逻辑关联(比如都属于 “用户” 或 “订单” 相关数据),这样更便于管理和查询。
例如,可以创建一个名为products的集合,用来存储各类商品信息,其中的文档可以有完全不同的字段:

// 插入第一个文档(包含名称、价格、类别字段)
db.products.insertOne({ name: "笔记本电脑", price: 5999, category: "电子设备" })

// 插入第二个文档(比第一个多了“品牌”和“库存”字段,少了“类别”字段)
db.products.insertOne({ name: "机械键盘", price: 399, brand: "Keychron", stock: 120 })

// 插入第三个文档(字段与前两个完全不同,包含“重量”和“材质”)
db.products.insertOne({ name: "帆布包", weight: 0.3, material: "棉麻" })

当执行第一条insertOne命令时,products集合会被自动创建,后续即使插入结构差异很大的文档,集合也能正常存储。这种灵活性让 MongoDB 非常适合处理数据格式多变的场景(比如电商平台中不同类型商品的属性差异),无需像关系型数据库那样为每种商品单独建表。

// 创建集合(插入第一个文档时自动创建)
> db.users.insertOne({"name": "王五", "age": 28})


// 查看所有集合
> show collections
users
products

// 查看集合中的文档数量
> db.users.countDocuments()
1

集合命名规则:

  • 不能为空字符串
  • 不能包含空字符(\0)
  • 不能以"system."开头(系统保留)
  • 避免使用$符号

固定集合(Capped Collection):固定集合是大小固定的集合,类似于循环缓冲区。

// 创建固定集合,大小100000字节
> db.createCollection("logs", {capped: true, size: 100000})

// 固定集合的特点:
// 1. 大小固定,超出时会删除最旧的文档
// 2. 不能删除单个文档,只能删除整个集合
// 3. 适合存储日志等时间序列数据

系统集合:MongoDB在每个数据库中都有系统集合,用于存储元数据:

// 查看系统集合
> db.system.namespaces.find()  // 所有集合信息
> db.system.indexes.find()     // 所有索引信息
> db.system.users.find()       // 用户信息
> db.system.profile.find()     // 性能分析信息

1.4.5 数据类型详解

MongoDB支持丰富的数据类型:

数据类型 描述
String 字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。
Integer 整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。
Boolean 布尔值。用于存储布尔值(真/假)。
Double 双精度浮点值。用于存储浮点值。
Min/Max keys 将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比。
Array 用于将数组或列表或多个值存储为一个键。
Timestamp 时间戳。记录文档修改或添加的具体时间。
Object 用于内嵌文档。
Null 用于创建空值。
Symbol 符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。
Date 日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。
Object ID 对象 ID。用于创建文档的 ID。
Binary Data 二进制数据。用于存储二进制数据。
Code 代码类型。用于在文档中存储 JavaScript 代码。
Regular expression 正则表达式类型。用于存储正则表达式。

例如:

// 字符串
{"name": "张三"}

// 数字
{"age": 25, "price": 99.99}

// 布尔值
{"isActive": true}

// 日期
{"created_at": new Date()}

// 数组
{"tags": ["技术", "编程", "数据库"]}

// 对象
{"address": {"city": "北京", "street": "中关村"}}

// 空值
{"description": null}

下面说明下几种重要的数据类型。

1.4.5.1 ObjectId - 自动生成的主键

每个文档都有一个唯一的_id字段,类似唯一主键,默认是ObjectId类型。

在这里插入图片描述

// ObjectId的组成(12字节)
// 前4字节:时间戳(unix 时间戳,格林尼治时间 UTC 时间,比北京时间晚了 8 个小时)
// 接下来3字节:机器标识
// 接下来2字节:进程ID
// 最后3字节:随机数

MongoDB 中存储的文档必须有一个 _id 键。这个键的值可以是任何类型的,默认是个 ObjectId 对象
由于 ObjectId 中保存了创建的时间戳,所以你不需要为你的文档保存时间戳字段,你可以通过 getTimestamp 函数来获取文档的创建时间,例如:

// 获取ObjectId的创建时间
> var id = ObjectId()
> id.getTimestamp()
ISODate("2024-01-15T10:30:00Z")

// ObjectId转字符串
> id.toString()
"65a4b8c0123456789012345"
1.4.5.2 Date - 日期时间

表示当前距离 Unix新纪元(1970年1月1日)的毫秒数。日期类型是有符号的, 负数表示 1970 年之前的日期。

> var mydate1 = new Date()     //格林尼治时间
> mydate1
ISODate("2018-03-04T14:58:51.233Z")
> typeof mydate1
object
> var mydate2 = ISODate() //格林尼治时间
> mydate2
ISODate("2018-03-04T15:00:45.479Z")
> typeof mydate2
object

这样创建的时间是日期类型,需要返回一个时间类型的字符串,可以:

> var mydate1str = mydate1.toString()
> mydate1str
Sun Mar 04 2018 14:58:51 GMT+0000 (UTC) 
> typeof mydate1str
string

或者

> Date()
Sun Mar 04 2018 15:02:59 GMT+0000 (UTC)   
1.4.5.3 其它特殊类型
// 时间戳(MongoDB内部使用)
{"timestamp": new Timestamp()}

// 二进制数据
{"file": BinData(0, "base64encodeddata")}

// JavaScript代码
{"script": Code("function() { return 'hello'; }")}

// 正则表达式
{"pattern": /^[a-z]+$/}

1.5 用户管理

MongoDB的用户管理就像给房子安装门锁一样,确保只有有权限的人才能访问数据库。如果你的数据库没有用户管理,任何人都可以连接进来查看、修改甚至删除你的数据,这是非常危险的。

用户管理包括:

  • 创建用户账号
  • 设置密码
  • 分配权限(角色)
  • 验证身份
  • 管理用户

1.5.1 用户和数据库的关系

在MongoDB中,用户是创建在特定数据库中的,但这个用户可以在多个数据库中拥有不同的权限。
例如:

// 在admin数据库中创建用户
use admin
db.createUser({
  user: "admin",
  pwd: "admin123",
  roles: ["userAdminAnyDatabase", "readWriteAnyDatabase"]
})

// 在myapp数据库中创建用户
use myapp
db.createUser({
  user: "appuser",
  pwd: "app123",
  roles: ["readWrite"]
})

其中的roles: ["userAdminAnyDatabase", "readWriteAnyDatabase"]这两个是 MongoDB 内置的全局角色,用于授予用户跨数据库级的管理和操作权限。

具体说明:

  • userAdminAnyDatabase:允许用户管理所有数据库中的用户(创建、修改、删除用户和角色),但不包含数据库数据的读写权限。
  • readWriteAnyDatabase:允许用户对所有数据库执行读写操作(插入、查询、更新、删除文档等),但不包含用户管理权限。

这两个角色组合后,admin 用户就具备了 “管理所有数据库的用户” 和 “操作所有数据库数据” 的超级权限,适合作为超级管理员” 账号(通常仅在 admin 数据库中创建这类高权限用户)。

对比我这里创建的 appuser用户:

  • 角色readWrite未指定数据库(默认作用于当前数据库 myapp),因此该用户仅能读写myapp数据库,权限范围局限于单个数据库,更适合业务应用使用。

高权限用户通常创建在 admin 数据库并使用全局角色,普通用户创建在业务数据库并使用局部角色。

1.5.2 角色(Roles)的概念

角色决定了用户能做什么:

  • read:只能读取数据
  • readWrite:可以读取和写入数据
  • dbAdmin:可以管理数据库(创建集合、索引等)
  • userAdmin:可以管理用户
  • clusterAdmin:可以管理整个集群

1.5.3 第一步:连接到MongoDB

使用MongoDB Shell连接

# 连接到本地MongoDB(默认端口27017)
mongosh

# 连接到远程MongoDB
mongosh --host 192.168.1.100 --port 27017

# 连接到特定数据库,例如我这里的myapp
mongosh --host localhost --port 27017 --db myapp
1.5.3.1 连接后的基本操作
// 查看当前数据库
db

// 查看所有数据库
show dbs

// 切换到指定数据库
use myapp

// 查看当前数据库的所有集合
show collections

1.5.4 第二步:创建第一个用户

1.5.4.1 创建管理员用户

首先创建一个超级管理员用户,这个用户可以管理所有数据库:

// 切换到admin数据库
use admin

// 创建管理员用户
db.createUser({
  user: "admin",
  pwd: "admin123",
  roles: [
    { role: "userAdminAnyDatabase", db: "admin" },
    { role: "readWriteAnyDatabase", db: "admin" },
    { role: "dbAdminAnyDatabase", db: "admin" }
  ]
})

解释:

  • user: 用户名
  • pwd: 密码
  • roles: 角色数组,每个角色包含:
    • role: 角色名称
    • db: 该角色适用的数据库
1.5.4.2 创建应用程序用户

为应用程序创建专用用户:

// 切换到应用程序数据库
use myapp

// 创建应用程序用户
db.createUser({
  user: "appuser",
  pwd: "app123",
  roles: [
    { role: "readWrite", db: "myapp" },
    { role: "read", db: "reports" }
  ]
})
1.5.4.3 创建只读用户

为报表系统创建只读用户:

// 创建只读用户
db.createUser({
  user: "readonly",
  pwd: "read123",
  roles: [
    { role: "read", db: "myapp" },
    { role: "read", db: "reports" }
  ]
})

1.5.5 第三步:启用身份验证

1.5.5.1 方法一:命令行启动时启用
# 启动MongoDB并启用认证
mongod --auth --dbpath /data/db
1.5.5.2 方法二:配置文件方式

创建配置文件 mongod.conf

# 存储配置
storage:
  dbPath: /var/lib/mongodb

# 网络配置
net:
  port: 27017
  bindIp: 127.0.0.1

# 安全配置
security:
  authorization: enabled

使用配置文件启动:

mongod --config /etc/mongod.conf

重启 MongoDB 服务

sudo systemctl restart mongod

1.5.6 第四步:使用用户身份连接

1.5.6.1 连接到MongoDB并认证
# 连接到MongoDB
mongosh --host localhost --port 27017

# 在shell中进行认证
use admin
db.auth("admin", "admin123")
1.5.6.2 直接使用认证信息连接
# 使用管理员用户连接
mongosh --host localhost --port 27017 -u "admin" -p "admin123" --authenticationDatabase "admin"

# 使用应用程序用户连接
mongosh --host localhost --port 27017 -u "appuser" -p "app123" --authenticationDatabase "myapp"

1.5.7 第五步:用户管理操作

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

// 查看特定用户
db.getUser("appuser")
1.5.7.2 修改用户信息
// 修改用户密码
db.changeUserPassword("appuser", "newpassword123")

// 更新用户角色
db.updateUser("appuser", {
  roles: [
    { role: "readWrite", db: "myapp" },
    { role: "read", db: "reports" },
    { role: "read", db: "analytics" }
  ]
})
1.5.7.3 删除用户
// 删除用户
db.dropUser("readonly")

1.5.8 实际应用场景

1.5.8.1 场景一:Web应用程序
// 为Web应用创建用户
use webapp
db.createUser({
  user: "webuser",
  pwd: "web123",
  roles: [
    { role: "readWrite", db: "webapp" }
  ]
})

// 应用程序连接字符串
// mongodb://webuser:web123@localhost:27017/webapp
1.5.8.2 场景二:数据分析系统
// 为数据分析创建只读用户
use analytics
db.createUser({
  user: "analyst",
  pwd: "analyst123",
  roles: [
    { role: "read", db: "analytics" },
    { role: "read", db: "reports" }
  ]
})
1.5.8.3 场景三:多租户系统
// 为每个租户创建独立用户
use tenant1
db.createUser({
  user: "tenant1_user",
  pwd: "tenant1_pass",
  roles: [
    { role: "readWrite", db: "tenant1" }
  ]
})

use tenant2
db.createUser({
  user: "tenant2_user",
  pwd: "tenant2_pass",
  roles: [
    { role: "readWrite", db: "tenant2" }
  ]
})

1.5.9 高级用户管理

1.5.9.1 创建自定义角色
// 创建自定义角色
use admin
db.createRole({
  role: "dataAnalyst",
  privileges: [
    {
      resource: { db: "analytics", collection: "" },
      actions: ["find", "aggregate"]
    }
  ],
  roles: []
})

// 为用户分配自定义角色
use analytics
db.grantRolesToUser("analyst", [
  { role: "dataAnalyst", db: "admin" }
])

db.grantRolesToUser() 是 MongoDB 中用于为已有用户分配角色的命令,作用是向指定用户授予新的权限角色,从而扩展该用户的操作权限。其中:

  • 第一个参数 “analyst” 是目标用户名(即要给哪个用户分配角色)。
  • 第二个参数是角色数组,这里指定了要授予的角色:
    role: "dataAnalyst":要分配的自定义角色名称(之前在 admin 数据库中创建的角色)。
    db: "admin":该角色的所属数据库(因为 dataAnalyst 是在 admin 数据库中创建的,必须明确指定来源)。
1.5.9.2 用户权限验证
// 检查用户权限
db.runCommand({
  usersInfo: "appuser",
  showPrivileges: true
})

1.5.10 完整示例:搭建安全的MongoDB环境

步骤1:启动MongoDB
# 启动MongoDB(开发环境)
mongod --dbpath ./data --port 27017
步骤2:创建管理员用户
// 连接到MongoDB
mongosh

// 创建管理员用户
use admin
db.createUser({
  user: "admin",
  pwd: "admin123",
  roles: [
    { role: "userAdminAnyDatabase", db: "admin" },
    { role: "readWriteAnyDatabase", db: "admin" },
    { role: "dbAdminAnyDatabase", db: "admin" }
  ]
})
步骤3:启用认证并重启
# 停止MongoDB
# Ctrl+C 或 pkill mongod

# 启用认证启动
mongod --auth --dbpath ./data --port 27017
步骤4:创建应用程序用户
// 使用管理员身份连接
mongosh -u "admin" -p "admin123" --authenticationDatabase "admin"

// 创建应用程序数据库和用户
use myapp
db.createUser({
  user: "appuser",
  pwd: "app123",
  roles: [
    { role: "readWrite", db: "myapp" }
  ]
})

// 测试应用程序用户
use myapp
db.auth("appuser", "app123")
步骤5:测试连接
// 插入测试数据
db.users.insertOne({
  name: "张三",
  email: "zhangsan@example.com",
  created_at: new Date()
})

// 查询数据
db.users.find()

1.6 连接

使用 MongoDB shell 来连接 MongoDB 服务器,标准的 URI 连接语法:

mongodb://[username:password@]host1[:port1][,...hostN[:portN]][/[defaultauthdb][?options]]
  • mongodb://:协议头,表示使用 MongoDB。
  • [username:password@]:(可选)认证信息,包括用户名和密码。
  • host1[:port1][,...hostN[:portN]]:服务器地址和端口,可以是一个或多个 MongoDB 服务器的地址和端口。
  • /[defaultauthdb]:(可选)默认认证数据库。
  • [?options]:(可选)连接选项。

标准的连接格式包含了多个选项(options),如下所示:

  • authSource:指定认证数据库。
  • replicaSet:指定副本集的名称。
  • ssl:启用 SSL 连接(true 或 false)。
  • readPreference:指定读偏好,如 primary, primaryPreferred, secondary, secondaryPreferred, nearest。
  • connectTimeoutMS:指定连接超时时间(毫秒)。
  • socketTimeoutMS:指定套接字超时时间(毫秒)。

一些示例:

连接到本地 MongoDB 实例(默认端口 27017):
mongodb://localhost

连接到本地 MongoDB 实例,指定数据库:
mongodb://localhost/mydatabase

使用用户名和密码连接到本地 MongoDB 实例:
mongodb://username:password@localhost/mydatabase

连接到远程 MongoDB 实例:
mongodb://remotehost:27017

连接到副本集(Replica Set):
mongodb://host1:27017,host2:27017,host3:27017/mydatabase?replicaSet=myReplicaSet

使用 SSL 连接到 MongoDB:
mongodb://username:password@localhost:27017/mydatabase?ssl=true

使用多个选项连接:
mongodb://username:password@localhost:27017/mydatabase?authSource=admin&ssl=true

1.7 实际应用示例

1.7.1 用户管理系统

// 1. 切换到(或创建)名为"userManagement"的数据库
// 如果该数据库不存在,会在首次插入数据时自动创建
use userManagement

// 2. 向"users"集合中插入一条用户文档
// "users"集合会在首次插入时自动创建
db.users.insertOne({
  "username": "zhangsan",  // 用户名(唯一标识,字符串类型)
  "email": "zhangsan@example.com",  // 邮箱(字符串类型)
  "profile": {  // 个人资料(嵌套文档,存储复杂信息)
    "firstName": "张",  // 名
    "lastName": "三",   // 姓
    "age": 25,          // 年龄(数字类型)
    "location": "北京"  // 所在地(字符串类型)
  },
  "roles": ["user", "editor"],  // 角色(数组类型,用户可拥有多个角色)
  "created_at": new Date(),  // 创建时间(Date类型,自动生成当前时间)
  "isActive": true  // 账号状态(布尔类型,true表示激活)
})

// 3. 查询指定用户的信息
// findOne():返回符合条件的第一个文档
// 查询条件:用户名(username)为"zhangsan"
db.users.findOne({"username": "zhangsan"})

// 4. 更新用户信息
// updateOne():更新符合条件的第一个文档
db.users.updateOne(
  {"username": "zhangsan"},  // 更新条件:匹配用户名"zhangsan"的文档
  {"$set": {"profile.age": 26}}  // 更新操作:$set操作符用于修改指定字段的值
  // 这里将嵌套文档profile中的age字段从25更新为26
)

1.7.2 博客系统

// 1. 向博客文章集合(posts)中插入一篇博客文章文档
// 集合(posts)会在首次插入文档时自动创建
db.posts.insertOne({
  "title": "MongoDB入门指南",  // 博客标题(字符串类型)
  "content": "MongoDB是一个文档型数据库...",  // 博客正文内容(字符串类型)
  "author": "张三",  // 作者名称(字符串类型)
  "tags": ["数据库", "MongoDB", "教程"],  // 标签(数组类型,存储多个字符串)
  "comments": [  // 评论列表(数组类型,存储嵌套文档)
    {
      "user": "李四",  // 评论用户
      "content": "写得很好!",  // 评论内容
      "created_at": new Date()  // 评论时间(Date类型,自动生成当前时间)
    }
  ],
  "published_at": new Date(),  // 发布时间(Date类型,自动生成当前时间)
  "viewCount": 0  // 阅读量(数字类型,初始为0)
})

// 2. 向指定博客文章添加新评论
// 使用updateOne方法更新文档,通过$push操作符向数组添加元素
db.posts.updateOne(
  {"title": "MongoDB入门指南"},  // 更新条件:匹配标题为"MongoDB入门指南"的文档
  {"$push": {  // $push操作符:向数组字段添加新元素(不覆盖原有元素)
    "comments": {  // 目标数组字段:comments(评论列表)
      "user": "王五",  // 新评论的用户
      "content": "学习了!",  // 新评论的内容
      "created_at": new Date()  // 新评论的时间(当前时间)
    }
  }}
)
// 执行后,该博客的comments数组会包含两条评论:李四和王五的评论

网站公告

今日签到

点亮在社区的每一天
去签到