# MongoDB 简介

URL: https://caijiao.org/express/chapter6/1-mongodb
Source: docs/express/chapter6/1-mongodb.md
Description: 本章节介绍 MongoDB 数据库的基本概念，讲解如何将 Express 应用与 MongoDB 集成，并实现基本的数据库操作。

MongoDB 是一个开源的文档数据库，属于 NoSQL 数据库的一种，它使用类似 JSON 格式的 BSON（Binary JSON）来存储数据。与传统的关系型数据库不同，MongoDB 不使用表格来存储数据，而是使用集合（Collections）来存储多个文档（Documents）。每个文档类似于 JSON 对象，具有键值对结构。

MongoDB 在处理大规模数据时具有显著的性能优势，尤其在需要灵活、可扩展的数据存储和快速查询的应用中表现出色。

## MongoDB 的基本特点

1. **文档存储**：MongoDB 使用文档（Document）存储数据，每个文档是一个 JSON 对象，可以包含嵌套的数组或对象。
2. **灵活的数据结构**：每个文档不需要严格遵循相同的结构，可以具有不同的字段和数据类型。
3. **水平扩展**：MongoDB 支持通过分片（Sharding）来水平扩展，能够处理大量数据。
4. **高可用性**：通过副本集（Replica Set）来实现数据的高可用性，保证数据库在节点故障时能够自动切换。
5. **聚合操作**：MongoDB 提供强大的聚合框架，可以执行复杂的数据处理和分析任务。

## 安装 MongoDB

在使用 MongoDB 前，我们需要先安装 MongoDB 数据库。

### 1.1 在本地安装 MongoDB

- **Windows**：可以通过 MongoDB 官方网站下载 MongoDB 的安装包并进行安装。
- **MacOS**：可以使用 Homebrew 安装 MongoDB。
  ```bash
  brew tap mongodb/brew
  brew install mongodb-community@5.0
````

* **Linux**：可以通过操作系统的包管理工具（如 `apt` 或 `yum`）安装 MongoDB。

### 1.2 启动 MongoDB 服务

在安装完成后，可以启动 MongoDB 服务：

```bash
mongod
```

默认情况下，MongoDB 会监听 27017 端口。

## 使用 MongoDB 与 Express 集成

在 Express 应用中，我们通常使用 MongoDB 官方的 Node.js 驱动程序或 Mongoose ODM 来与 MongoDB 进行交互。Mongoose 是一个更为常用的工具，它提供了基于模型的方式来操作 MongoDB，能够简化与数据库的交互。

### 2.1 安装 Mongoose

首先，安装 Mongoose：

```bash
npm install mongoose
```

### 2.2 连接 MongoDB 数据库

在 Express 应用中，我们可以使用 Mongoose 连接到 MongoDB 数据库。以下是连接到 MongoDB 的示例代码：

```js
const mongoose = require('mongoose');

// 连接到 MongoDB 数据库
mongoose.connect('mongodb://localhost:27017/expressTutorial', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
})
  .then(() => console.log('MongoDB 连接成功'))
  .catch((err) => console.error('MongoDB 连接失败', err));
```

`mongodb://localhost:27017/expressTutorial` 是 MongoDB 连接字符串，其中 `expressTutorial` 是数据库名称。

### 2.3 创建 Mongoose 模型

Mongoose 使用 Schema 定义文档的结构，之后基于该结构创建模型。模型是与 MongoDB 集合进行交互的桥梁。

#### 2.3.1 定义 Schema

```js
const mongoose = require('mongoose');

// 定义用户 Schema
const userSchema = new mongoose.Schema({
  username: {
    type: String,
    required: true,
    unique: true,
  },
  email: {
    type: String,
    required: true,
    unique: true,
  },
  password: {
    type: String,
    required: true,
  },
  createdAt: {
    type: Date,
    default: Date.now,
  },
});

// 创建模型
const User = mongoose.model('User', userSchema);
```

#### 2.3.2 创建文档

```js
// 创建一个新用户
const newUser = new User({
  username: 'john_doe',
  email: 'john.doe@example.com',
  password: 'securePassword',
});

newUser.save()
  .then(() => console.log('用户创建成功'))
  .catch((err) => console.error('用户创建失败', err));
```

### 2.4 查询 MongoDB 数据

Mongoose 提供了多种方法来查询数据库。例如，查询所有用户、查询单个用户等。

#### 2.4.1 查询所有用户

```js
User.find()
  .then((users) => console.log(users))
  .catch((err) => console.error('查询失败', err));
```

#### 2.4.2 查询单个用户

```js
User.findOne({ username: 'john_doe' })
  .then((user) => console.log(user))
  .catch((err) => console.error('查询失败', err));
```

#### 2.4.3 使用条件查询

```js
User.find({ email: 'john.doe@example.com' })
  .then((users) => console.log(users))
  .catch((err) => console.error('查询失败', err));
```

### 2.5 更新数据

Mongoose 还支持更新文档，以下是更新用户的示例：

```js
User.updateOne({ username: 'john_doe' }, { password: 'newSecurePassword' })
  .then(() => console.log('用户密码更新成功'))
  .catch((err) => console.error('更新失败', err));
```

### 2.6 删除数据

我们还可以删除数据库中的文档：

```js
User.deleteOne({ username: 'john_doe' })
  .then(() => console.log('用户删除成功'))
  .catch((err) => console.error('删除失败', err));
```

## 总结

MongoDB 是一个非常灵活、扩展性强的 NoSQL 数据库，适用于需要处理大规模数据和高并发的应用。在 Express 中，使用 Mongoose 可以非常方便地与 MongoDB 进行集成，进行各种数据库操作。

* MongoDB 使用文档存储数据，每个文档是一个 JSON 对象。
* 使用 Mongoose，可以通过定义 Schema 和模型来管理 MongoDB 的数据。
* 通过 Mongoose 提供的 API，可以方便地进行增、查、改、删等操作。
