MongoDB 基础教程:快速入门指南 – wiki基地


MongoDB 基础教程:快速入门指南

1. 引言:数据库的演变与 MongoDB 的崛起

在计算机科学和信息技术的漫长发展历程中,数据存储和管理一直是核心议题。早期,关系型数据库(RDBMS)凭借其严谨的结构化特性和强大的事务支持,成为了数据存储的主流。MySQL、PostgreSQL、Oracle 等都是其中的佼佼者。它们基于表格、行、列以及预定义的模式(Schema),通过 SQL(Structured Query Language)进行数据操作,并严格遵守 ACID 原则(原子性、一致性、隔离性、持久性)。

然而,随着互联网的爆炸式增长、Web 2.0 应用的兴起以及移动互联网和物联网时代的到来,我们面临的数据类型越来越多样化,数据量呈几何级数增长,应用的需求也变得更加灵活多变。传统的 RDBMS 在处理海量非结构化/半结构化数据、应对高并发读写以及实现快速迭代的应用需求时,开始显现出一些局限性,例如:

  • 模式僵化: 预定义的模式使得面对频繁变化的需求时,修改数据库结构变得复杂且耗时。
  • 横向扩展困难: 关系型数据库通常倾向于纵向扩展(提升单台服务器性能),而横向扩展(增加服务器数量)实现高可用和分布式存储则相对复杂且昂贵。
  • 处理复杂数据类型不便: 对于嵌套结构、数组等数据,关系型数据库需要通过多张表关联来表示,操作繁琐。

正是在这样的背景下,”NoSQL”(Not only SQL)数据库应运而生。NoSQL 数据库是一个广泛的概念,它涵盖了多种不同类型的数据存储系统,它们放弃了传统关系型数据库的一些特性,比如严格的模式、联接操作、ACID 事务(在某些场景下)。NoSQL 数据库通常提供更高的可用性、更灵活的数据模型以及更强的水平扩展能力,以应对大规模分布式应用的需求。

MongoDB 是 NoSQL 数据库家族中一颗耀眼的明星,属于 文档型数据库。它以其灵活的数据模型、高性能、易于扩展和丰富的功能集,迅速获得了开发者社区的青睐,广泛应用于 Web 应用、移动应用、大数据、内容管理系统等多种场景。

本篇教程旨在为初学者提供一个快速入门 MongoDB 的指南,帮助你理解其核心概念,掌握基本的安装和数据操作方法。

2. MongoDB 的核心概念:文档、集合与数据库

理解 MongoDB 的核心概念是掌握它的第一步。与关系型数据库的“库-表-行”结构不同,MongoDB 使用的是“库-集合-文档”结构。

  • 数据库 (Database):
    数据库是 MongoDB 中最高层级的组织单位,用于逻辑上划分和隔离不同的数据集合。在一个 MongoDB 实例中可以创建多个数据库,每个数据库都有自己的集合。默认情况下,MongoDB 有一些内置的数据库,比如 admin (存储用户认证等管理信息)、local (存储本地复制集配置信息) 等。当你创建第一个集合并插入第一个文档时,如果指定的数据库不存在,MongoDB 会自动创建它。

  • 集合 (Collection):
    集合是文档的容器,类似于关系型数据库中的“表”。一个数据库中可以包含多个集合。集合是无模式(schema-less)的,这意味着同一个集合中的文档可以拥有完全不同的结构(字段、数据类型),尽管在实际应用中,通常会保持文档结构相对一致以便于查询和管理。当你向一个不存在的集合插入第一个文档时,MongoDB 会自动创建这个集合。

  • 文档 (Document):
    文档是 MongoDB 中的最小数据单元,也是核心概念。文档存储数据,格式类似于 JSON(JavaScript Object Notation),但实际上使用的是 BSON (Binary JSON) 格式。BSON 是 JSON 的二进制表示,它在 JSON 的基础上增加了更多的数据类型(如日期、二进制数据、长整型等),并提高了存储和扫描效率。

    一个文档由一系列的键值对(field-value pairs)组成,例如:

    json
    {
    "_id": ObjectId("..."), // 每个文档都会有一个唯一的 _id 字段
    "name": "Alice",
    "age": 30,
    "city": "New York",
    "interests": ["reading", "hiking"],
    "contact": {
    "email": "[email protected]",
    "phone": "123-456-7890"
    },
    "isActive": true,
    "createdAt": ISODate("...")
    }

    文档具有以下特点:
    * 无模式: 同一个集合中的文档可以有不同的字段和结构。这提供了极大的灵活性,尤其适合处理结构不固定的数据。
    * 内嵌文档和数组: 文档内部可以包含其他文档(如上面的 contact 字段)或数组(如上面的 interests 字段)。这种嵌套结构允许以一种非常自然的方式表示复杂关系,减少了像关系型数据库中常见的联接(JOIN)操作的需求。
    * _id 字段: 每个文档在创建时都会自动添加一个 _id 字段,作为文档的唯一标识符。如果插入文档时没有指定 _id,MongoDB 会自动生成一个 ObjectId 类型的值作为 _idObjectId 是一种特殊的数据类型,包含时间戳、机器标识、进程ID 和计数器,保证了在分布式环境下的唯一性。

类比:

如果你习惯关系型数据库,可以做一个简单的类比来理解 MongoDB 的结构:

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

但请记住,这个类比并不完全精确,尤其是在模式和联接方面,MongoDB 的设计理念有显著不同。

3. 安装 MongoDB

要开始使用 MongoDB,首先需要在你的计算机上安装它。MongoDB 提供了多种安装方式,包括本地安装、Docker 容器、以及云服务(如 MongoDB Atlas)。这里我们介绍最常见的本地安装方法。请根据你的操作系统选择相应的安装指南。

3.1. Windows

  1. 下载安装包: 访问 MongoDB 官方下载中心 (https://www.mongodb.com/try/download/community)。选择适合你 Windows 版本的 MongoDB Community Server MSI 安装包并下载。
  2. 运行安装程序: 双击下载的 .msi 文件。按照向导进行安装。
    • 选择 “Custom” 安装,以便选择安装路径和组件。
    • 重要: 在 “Service Configuration” 步骤,你可以选择将 MongoDB 安装为服务运行(推荐),并指定数据目录 (Data Directory) 和日志目录 (Log Directory)。确保这些目录有足够的权限供 MongoDB 写入。
    • 或者,你也可以选择不安服务,手动启动 mongod.exe
  3. 配置环境变量 (可选但推荐): 将 MongoDB 的 bin 目录添加到系统的 PATH 环境变量中,这样你可以在任何命令行窗口运行 mongodmongosh 命令,而无需进入安装目录。
    • 通常 bin 目录位于 C:\Program Files\MongoDB\Server\[版本号]\bin\
  4. 创建数据目录: 如果你在安装时没有配置服务自动创建数据目录,或者选择手动启动,你需要手动创建数据目录。默认是 C:\data\db。你可以通过 mongod --dbpath <你的数据目录> 来指定。
  5. 启动 MongoDB 服务器:
    • 作为服务安装: 如果安装为服务,通常安装完成后服务会自动启动。你可以通过 Windows 的服务管理器来启动、停止或重启 MongoDB 服务。
    • 手动启动: 打开命令提示符或 PowerShell,输入 mongod 命令(如果配置了环境变量)或者进入 MongoDB 安装目录的 bin 文件夹运行 mongod.exe。如果数据目录不是默认路径,需要使用 mongod --dbpath <你的数据目录>。看到类似 “waiting for connections on port 27017” 的输出表示服务器启动成功。
  6. 连接到 MongoDB: 打开另一个命令提示符或 PowerShell 窗口,输入 mongosh。如果连接成功,你会看到 test> 的提示符,表示你已连接到默认的 test 数据库。

3.2. macOS

通常使用 Homebrew 包管理器安装是最便捷的方式。

  1. 安装 Homebrew (如果未安装): 打开终端,运行 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  2. 安装 MongoDB: 打开终端,运行 brew tap mongodb/brew 添加 MongoDB 的 Tap,然后运行 brew install mongodb-community
  3. 启动 MongoDB 服务器: 运行 brew services start mongodb-community。MongoDB 将作为后台服务启动。
  4. 连接到 MongoDB: 打开终端,运行 mongosh

3.3. Linux (以 Ubuntu 为例)

MongoDB 提供了官方的 Apt 仓库。

  1. 导入公钥: 打开终端,运行 wget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | sudo apt-key add - (注意:版本号可能需要根据你安装的 MongoDB 版本调整,请查阅官方文档获取最新命令)。
  2. 创建列表文件: 运行 echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/6.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list (注意:这里的 focal 是 Ubuntu 的版本代号,6.0 是 MongoDB 版本,请根据你的系统和目标 MongoDB 版本调整)。
  3. 更新 Apt 缓存: 运行 sudo apt update
  4. 安装 MongoDB: 运行 sudo apt install -y mongodb-org
  5. 启动 MongoDB 服务器: 运行 sudo systemctl start mongod
  6. 验证服务状态: 运行 sudo systemctl status mongod
  7. 开机自启 (可选): 运行 sudo systemctl enable mongod
  8. 连接到 MongoDB: 打开终端,运行 mongosh

3.4. MongoDB Atlas (云服务)

如果你不想在本地安装和管理 MongoDB,可以使用 MongoDB Atlas。它提供免费的入门级集群,非常适合学习和测试。

  1. 访问 MongoDB Atlas 网站 (https://www.mongodb.com/cloud/atlas)。
  2. 注册并创建一个账户。
  3. 创建一个新的集群(选择免费的 M0 沙箱集群)。
  4. 配置集群的网络访问(通常设置为允许从你的当前 IP 地址连接)和数据库用户。
  5. 获取连接字符串。你可以在你的应用程序或 mongosh 中使用这个连接字符串来连接到你的 Atlas 集群。使用 mongosh 连接时,通常格式是 mongosh "mongodb+srv://<username>:<password>@<cluster-url>/<database-name>?retryWrites=true&w=majority"

连接成功后,你会在终端看到类似的提示符 (例如 test>),表示你已经准备好与 MongoDB 交互了。

4. 使用 mongosh 进行基本操作

mongosh 是 MongoDB 官方推荐的现代命令行 Shell 工具,用于与 MongoDB 实例进行交互。通过 mongosh,你可以执行各种数据库命令,进行数据 CRUD(创建、读取、更新、删除)操作,以及管理数据库。

当你成功运行 mongosh 并连接到数据库后,会看到一个命令行提示符,通常是当前数据库的名称(例如 test>)。

4.1. 切换数据库

使用 use <database_name> 命令来切换到指定的数据库。如果指定的数据库不存在,MongoDB 会在你第一次向其中插入数据时自动创建它。

javascript
use myNewDatabase; // 切换到 myNewDatabase 数据库
// 输出: switched to db myNewDatabase

你可以使用 db 命令来查看当前所在的数据库:

javascript
db; // 查看当前数据库
// 输出: myNewDatabase

使用 show dbs 命令可以列出当前 MongoDB 实例中的所有数据库:

javascript
show dbs; // 显示所有数据库
/* 输出示例:
admin 40.00 KiB
config 108.00 KiB
local 108.00 KiB
myNewDatabase 8.00 KiB // 如果你插入了数据,这里会显示大小
test 40.00 KiB
*/

4.2. 创建集合

在 MongoDB 中,你通常不需要显式创建集合。当你向一个不存在的集合插入第一个文档时,MongoDB 会自动创建该集合。

不过,你也可以使用 db.createCollection() 方法显式创建集合,并可以指定一些配置选项(如设置大小限制、验证规则等),但在快速入门阶段,通常不需要这样做。

javascript
// 显式创建一个名为 'users' 的集合
db.createCollection("users");
// 输出: { ok: 1 }

使用 show collections 命令可以列出当前数据库中的所有集合:

javascript
show collections; // 显示当前数据库中的所有集合
/* 输出示例:
users
*/

5. CRUD 操作:数据的增、查、改、删

CRUD 是数据库操作的核心,即 Create (创建)、Read (读取)、Update (更新) 和 Delete (删除)。在 MongoDB 中,这些操作主要通过 db.collection 对象上的方法来完成。

5.1. 创建 (Create / Insert)

用于向集合中添加新文档。

  • db.collection.insertOne(document, options): 向集合中插入一个文档。
  • db.collection.insertMany([documents], options): 向集合中插入多个文档(以数组形式提供)。

示例:插入单个文档

切换到 myNewDatabase 数据库,并向 users 集合插入一个文档:

“`javascript
use myNewDatabase;

db.users.insertOne({
name: “Alice”,
age: 30,
city: “New York”,
interests: [“reading”, “hiking”],
isActive: true
});
/ 输出示例:
{
acknowledged: true,
insertedId: ObjectId(“65fef…a1b2c”) // MongoDB 自动生成的 _id
}
/
“`

示例:插入多个文档

javascript
db.users.insertMany([
{
name: "Bob",
age: 25,
city: "Los Angeles",
interests: ["coding", "gaming"],
isActive: true
},
{
name: "Charlie",
age: 35,
city: "Chicago",
interests: ["cooking", "travel"],
isActive: false
},
{
name: "David",
age: 28,
city: "New York", // 注意 David 也在 New York
interests: ["music", "photography"],
isActive: true
}
]);
/* 输出示例:
{
acknowledged: true,
insertedIds: {
'0': ObjectId("65fef...d3e4f"),
'1': ObjectId("65fef...f5g6h"),
'2': ObjectId("65fef...h7i8j")
}
}
*/

5.2. 读取 (Read / Find)

用于从集合中查询文档。

  • db.collection.find(query, projection): 查询符合条件的文档,并返回一个游标 (Cursor)。
    • query: 一个文档,用于指定查询条件(类似于 SQL 的 WHERE 子句)。如果省略或使用 {},则返回集合中的所有文档。
    • projection (可选): 一个文档,用于指定返回的字段(类似于 SQL 的 SELECT 子句)。指定字段值为 1 表示包含该字段,0 表示排除该字段。_id 字段默认包含,除非显式设置为 0 排除。
  • db.collection.findOne(query, projection): 查询符合条件的 第一个 文档。

find() 方法返回的是一个游标,你可以迭代游标来获取文档。在 mongosh 中,当你直接输入 db.collection.find() 命令时,Shell 会自动迭代游标并打印前20个文档。

示例:查询所有文档

javascript
db.users.find(); // 查询 users 集合中的所有文档

示例:查询符合特定条件的文档

查询年龄大于等于 30 岁的用户:

javascript
db.users.find({ age: { $gte: 30 } });
// $gte 是比较运算符,表示 "大于等于" (Greater Than or Equal)
// 其他常用的比较运算符:
// $eq: 等于 (Equal) - 可以省略,直接 { field: value } 即为 $eq
// $ne: 不等于 (Not Equal)
// $gt: 大于 (Greater Than)
// $lt: 小于 (Less Than)
// $lte: 小于等于 (Less Than or Equal)
// $in: 字段值在指定数组中
// $nin: 字段值不在指定数组中

查询居住在 “New York” 的用户:

javascript
db.users.find({ city: "New York" });

查询活跃(isActive: true)且年龄小于 30 岁的用户:

javascript
db.users.find({ isActive: true, age: { $lt: 30 } }); // 逗号连接多个条件相当于逻辑 AND

查询居住在 “New York” 或 “Los Angeles” 的用户:

javascript
db.users.find({ $or: [{ city: "New York" }, { city: "Los Angeles" }] }); // $or 用于逻辑 OR 操作
// 其他逻辑运算符:
// $and: 逻辑 AND (默认就是 AND,通常用于复杂组合)
// $not: 逻辑 NOT
// $nor: 逻辑 NOR (都不满足)

查询兴趣包含 “coding” 的用户:

javascript
db.users.find({ interests: "coding" }); // 查询数组字段是否包含某个值

查询既喜欢 “reading” 又喜欢 “hiking” 的用户:

javascript
db.users.find({ interests: { $all: ["reading", "hiking"] } }); // $all 要求数组包含所有指定元素

查询 interests 数组中恰好有两个元素的文档:

javascript
db.users.find({ interests: { $size: 2 } }); // $size 查询数组长度

查询拥有 contact 字段的文档:

javascript
db.users.find({ contact: { $exists: true } }); // $exists 查询字段是否存在

查询 age 字段类型是数值的文档:

javascript
db.users.find({ age: { $type: "number" } }); // $type 查询字段类型
// BSON 类型别名或编号:double (1), string (2), object (3), array (4), binary (5), undefined (6), ObjectId (7), boolean (8), date (9), null (10), regex (11), dbPointer (12), JavaScript (13), symbol (14), JavaScriptWithScope (15), 32-bit integer (16), timestamp (17), 64-bit integer (18), decimal (19), MinKey (255), MaxKey (127). 常用别名或编号。

查询 contact 子文档中 email 为 “[email protected]” 的文档:

javascript
db.users.find({ "contact.email": "[email protected]" }); // 使用点号 (.) 访问内嵌文档的字段

示例:指定返回的字段 (Projection)

只返回 namecity 字段,并排除 _id 字段:

javascript
db.users.find({}, { name: 1, city: 1, _id: 0 }); // 第一个 {} 表示查询所有文档,第二个 {} 指定投影

只返回 name 字段,包含默认的 _id 字段:

javascript
db.users.find({}, { name: 1 });

排除 interests 字段,返回其他所有字段:

javascript
db.users.find({}, { interests: 0 });

示例:findOne()

查询年龄大于 30 岁的第一个文档:

javascript
db.users.findOne({ age: { $gt: 30 } });

示例:链式调用(排序、限制数量、跳过)

查询所有用户,按年龄降序排序,只返回前 2 个文档:

javascript
db.users.find().sort({ age: -1 }).limit(2);
// sort(): 排序,{ field: 1 } 升序,{ field: -1 } 降序
// limit(): 限制返回的文档数量

查询所有用户,跳过前 1 个文档,再返回接下来的 2 个文档 (常用于分页):

javascript
db.users.find().skip(1).limit(2);
// skip(): 跳过指定数量的文档

可以将这些方法链式调用:

javascript
db.users.find(
{ city: "New York" }, // 查询条件
{ name: 1, age: 1 } // 投影
).sort({ age: 1 }).limit(1); // 先按年龄升序,然后只取第一个 (年龄最小的那个纽约客)

5.3. 更新 (Update)

用于修改集合中的现有文档。MongoDB 提供了灵活的更新操作符,允许你修改文档的特定字段,而不是替换整个文档。

  • db.collection.updateOne(filter, update, options): 更新符合条件的 第一个 文档。
    • filter: 查询条件,用于匹配要更新的文档。
    • update: 指定如何修改文档的更新操作符或新文档。
    • options (可选): 例如 upsert: true (如果文档不存在则插入)。
  • db.collection.updateMany(filter, update, options): 更新符合条件的 所有 文档。

重要的更新操作符:

  • $set: 设置字段值。如果字段不存在,则添加该字段。
  • $unset: 删除字段。
  • $inc: 对数字字段进行增减操作。
  • $push: 向数组字段末尾添加一个元素。如果字段不是数组,则会报错。如果字段不存在,则创建数组。
  • $addToSet: 向数组字段中添加一个元素,但只有当元素不存在时才添加(保证数组元素的唯一性)。
  • $pop: 从数组的开头 (-1) 或末尾 (1) 删除一个元素。
  • $pull: 从数组中删除所有匹配指定条件的元素。
  • $pullAll: 从数组中删除所有出现在指定数组中的元素。

示例:使用 $set 更新字段

将 Alice 的城市修改为 “Los Angeles”,并添加一个 status 字段:

javascript
db.users.updateOne(
{ name: "Alice" }, // 查找 Alice
{
$set: { // 使用 $set 操作符
city: "Los Angeles",
status: "Active"
}
}
);
/* 输出示例:
{
acknowledged: true,
insertedId: null,
matchedCount: 1, // 匹配到 1 个文档
modifiedCount: 1 // 修改了 1 个文档
}
*/

将所有活跃用户的 isActive 字段设置为 false

javascript
db.users.updateMany(
{ isActive: true }, // 查找所有活跃用户
{ $set: { isActive: false } } // 将 isActive 设置为 false
);

示例:使用 $inc 增加数值

将 Bob 的年龄增加 1:

javascript
db.users.updateOne(
{ name: "Bob" },
{ $inc: { age: 1 } } // age 字段增加 1
);

示例:使用 $push 添加数组元素

向 Alice 的兴趣列表添加 “swimming”:

javascript
db.users.updateOne(
{ name: "Alice" },
{ $push: { interests: "swimming" } }
);

示例:使用 $addToSet 添加唯一数组元素

向 Charlie 的兴趣列表添加 “reading”(如果不存在的话):

javascript
db.users.updateOne(
{ name: "Charlie" },
{ $addToSet: { interests: "reading" } } // 如果 Charlie 的 interests 中已经有 "reading",则不会重复添加
);

示例:使用 $pull 删除数组元素

从 David 的兴趣列表删除 “music”:

javascript
db.users.updateOne(
{ name: "David" },
{ $pull: { interests: "music" } } // 删除所有值为 "music" 的元素
);

示例:使用 $unset 删除字段

删除所有用户的 status 字段:

javascript
db.users.updateMany(
{}, // 匹配所有文档
{ $unset: { status: "" } } // 值可以是任意类型,通常用 "" 或 1
);

示例:使用 upsert: true (如果不存在则插入)

尝试更新一个名为 “Eve” 的用户,如果不存在则插入:

javascript
db.users.updateOne(
{ name: "Eve" },
{ $set: { age: 22, city: "Seattle" } },
{ upsert: true } // upsert 为 true,如果找不到匹配的文档,就根据 filter 和 update 的内容创建一个新文档
);
/* 输出示例:
{
acknowledged: true,
insertedId: ObjectId("65fef...k9l0m"), // 插入了一个新文档,返回新文档的 _id
matchedCount: 0, // 没有匹配到现有文档
modifiedCount: 0 // 没有修改现有文档
}
*/

替换整个文档:

如果你想完全替换一个文档的内容(保留 _id),可以使用 replaceOne 方法,或者在 updateOne/updateMany 中不使用任何操作符,直接提供一个新的文档体(但这不常用,且会删除原文档中新文档没有的字段)。通常推荐使用操作符进行局部更新。

javascript
// 替换 Alice 的文档 (危险操作,会删除所有未包含在新文档中的字段)
db.users.replaceOne(
{ name: "Alice" },
{
name: "Alice Smith",
age: 31,
city: "Los Angeles",
updatedAt: new Date()
}
);

5.4. 删除 (Delete)

用于从集合中删除文档。

  • db.collection.deleteOne(filter, options): 删除符合条件的 第一个 文档。
  • db.collection.deleteMany(filter, options): 删除符合条件的 所有 文档。

示例:删除单个文档

删除年龄小于 25 岁的第一个文档:

javascript
db.users.deleteOne({ age: { $lt: 25 } });

示例:删除多个文档

删除所有居住在 “Los Angeles” 的文档:

javascript
db.users.deleteMany({ city: "Los Angeles" });

示例:删除所有文档

javascript
db.users.deleteMany({}); // {} 作为 filter 会匹配所有文档

示例:删除集合

删除整个 users 集合及其所有文档:

javascript
db.users.drop();
// 输出: true (表示成功)

示例:删除数据库

删除当前数据库(例如 myNewDatabase):

javascript
db.dropDatabase();
// 输出: { "dropped": "myNewDatabase", "ok": 1 }

请谨慎使用 drop()dropDatabase() 命令,它们会永久删除数据!

6. 索引 (Indexes)

索引是数据库性能优化的关键。它们允许数据库在不扫描整个集合的情况下,快速找到特定字段的值。没有索引时,MongoDB 必须执行全集合扫描(collection scan)来查找匹配文档,这在大型集合中效率非常低下。

MongoDB 默认会自动在每个文档的 _id 字段上创建一个唯一索引。

  • db.collection.createIndex(keys, options): 在集合上创建一个索引。
    • keys: 一个文档,指定要创建索引的字段和索引方向(1 为升序,-1 为降序)。
    • options (可选): 例如 unique: true (创建唯一索引)、name (指定索引名称) 等。
  • db.collection.getIndexes(): 列出集合中所有索引。
  • db.collection.dropIndex(index): 删除指定的索引(按名称或键文档)。
  • db.collection.dropIndexes(): 删除集合中的所有索引(_id 索引除外)。

示例:创建单字段索引

age 字段上创建升序索引,以加快按年龄查询和排序的速度:

javascript
db.users.createIndex({ age: 1 });
/* 输出示例:
{
numIndexesBefore: 1, // _id 索引
numIndexesAfter: 2,
ok: 1
}
*/

city 字段上创建降序索引:

javascript
db.users.createIndex({ city: -1 });

示例:创建复合索引

cityage 字段上创建复合索引,先按城市升序,再按年龄降序:

javascript
db.users.createIndex({ city: 1, age: -1 });

复合索引对于涉及多个字段的查询(特别是查询条件和排序条件组合)非常有用。查询通常可以使用复合索引的前缀。例如,上面的 { city: 1, age: -1 } 索引可以加速 find({ city: "..." })find({ city: "...", age: { $gt: ... } }) 以及 find({ city: "..." }).sort({ age: -1 }) 等查询。

示例:创建唯一索引

email 字段上创建一个唯一索引,确保每个用户的 email 地址都是唯一的:

javascript
// 假设你的文档有 email 字段
db.users.createIndex({ email: 1 }, { unique: true });
// 如果集合中已经存在重复的 email 值,创建唯一索引会失败。

示例:查看索引

javascript
db.users.getIndexes();

示例:删除索引

通过名称删除索引(名称通常是字段名和方向的组合,如 age_1):

javascript
db.users.dropIndex("age_1");

或者通过键文档删除:

javascript
db.users.dropIndex({ city: 1, age: -1 });

正确地创建和使用索引是提升 MongoDB 查询性能的关键步骤。

7. 基本管理命令

除了数据操作,mongosh 也可以用来执行一些基本的管理任务。

  • show dbs;: 列出所有数据库。
  • use <database_name>;: 切换数据库。
  • show collections;: 列出当前数据库的所有集合。
  • db.stats();: 显示当前数据库的统计信息,包括集合数量、文档总数、数据大小等。
  • db.collection.stats();: 显示特定集合的统计信息。

8. 总结与后续学习方向

本教程带你快速了解了 MongoDB 的核心概念:数据库、集合和文档。你学会了如何在本地安装 MongoDB,使用 mongosh 连接到数据库,并掌握了最基础也是最重要的 CRUD 操作(创建、读取、更新、删除文档),以及如何通过索引来提升查询性能。

这仅仅是 MongoDB 强大功能的冰山一角。作为一款企业级的 NoSQL 数据库,MongoDB 还有许多高级特性值得深入学习,包括:

  • 聚合框架 (Aggregation Framework): 用于执行复杂的数据转换和分析操作,类似于 SQL 的 GROUP BY、JOIN(通过 $lookup 实现部分功能)、数据转换等。
  • 复制集 (Replication): 构建高可用性的 MongoDB 集群,确保数据冗余和故障转移。
  • 分片 (Sharding): 将数据分布到多个服务器上,实现水平扩展以处理海量数据。
  • 地理空间查询 (Geospatial Queries): 支持基于地理位置的数据查询。
  • 全文搜索 (Full-Text Search): 内置的文本搜索功能。
  • 事务 (Transactions): MongoDB 4.0+ 支持跨多个文档和集合的 ACID 事务(特别是对于复制集和分片集群)。
  • 安全 (Security): 用户认证、授权、加密等。
  • 驱动程序 (Drivers): 如何在各种编程语言(如 Node.js, Python, Java, C#, Go 等)中使用官方驱动程序连接和操作 MongoDB。

建议你接下来:

  1. 实践: 在本地环境中多加练习,尝试创建不同结构的文档,进行各种复杂的查询和更新操作。
  2. 深入学习: 阅读官方文档 (https://docs.mongodb.com/),它是最权威和详细的学习资源。
  3. 探索高级特性: 学习聚合框架、索引策略、复制集和分片等,为构建更强大、更可靠的应用打下基础。
  4. 结合编程语言: 学习如何在你熟悉的编程语言中使用 MongoDB 驱动程序进行开发。

MongoDB 凭借其灵活性和可扩展性,是现代应用程序开发的强大工具。通过持续学习和实践,你将能够充分发挥其优势,构建高性能、高可用的数据驱动应用。祝你在 MongoDB 的学习旅程中一切顺利!

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部