MongoDB 概述

MongoDB 是一个开源的 NoSQL 数据库,它基于文档存储,提供了高性能、高可扩展性、易用性等特性。MongoDB 使用 BSON(Binary JSON)格式存储数据,适合存储复杂的、非结构化的数据。本文将介绍 MongoDB 的基础概念、安装、常用命令及如何在实际应用中使用。

MongoDB 是一个基于文档的 NoSQL 数据库,采用 BSON 格式存储数据。它为开发人员提供了高效的读写能力,并且具有横向扩展的能力。MongoDB 支持灵活的数据模型,可以存储 JSON 风格的文档。

主要特点:

  • 文档型存储:MongoDB 存储数据的单元是文档,类似 JSON 格式,易于存储复杂的数据结构。
  • 高性能:MongoDB 支持高并发读写操作,适合大数据量的应用场景。
  • 可扩展性:MongoDB 支持水平扩展(Sharding),可以分布式部署,适应大规模数据存储。
  • 灵活的数据模式:可以在同一个集合中存储不同结构的文档。

MongoDB 安装

好的,下面我将针对 WindowsmacOS 系统,详细说明如何安装 MongoDB。我们将分为两部分进行讲解:Windows 安装 MongoDB 和 macOS 安装 MongoDB。

Windows

下载 MongoDB

  1. 访问 MongoDB 官方下载页面:MongoDB 下载页面
  2. 选择操作系统为 Windows,然后选择合适的 MongoDB 版本(通常选择最新版本),并选择 MSI 安装包格式。
  3. 点击 Download 按钮下载安装包。

安装 MongoDB

  1. 下载完成后,运行下载的 .msi 安装包,启动安装向导。
  2. 在安装向导中,选择 “Complete” 安装类型(这是默认选项,推荐选择)。
  3. 在 “Service Configuration” 步骤,确保选中 Install MongoDB as a Service(将 MongoDB 作为服务安装),并且选中 Run service as Network Service user
  4. 完成安装。

配置环境变量

  1. 安装完成后,需要将 MongoDB 的可执行文件路径添加到 系统的环境变量 中,这样可以在任何地方通过命令行启动 MongoDB。

  2. 打开 文件资源管理器,进入 MongoDB 的安装目录(默认安装路径为 C:\Program Files\MongoDB\Server\<version>\bin,例如 C:\Program Files\MongoDB\Server\6.0\bin)。

  3. 复制该目录路径。

  4. 打开 环境变量设置

    • 右键点击“此电脑”或“我的电脑”,选择 “属性”
    • 点击 “高级系统设置”,然后点击 “环境变量”
    • 系统变量 区域,找到并选择 Path,点击 编辑
    • 在编辑窗口中,点击 新建,粘贴刚才复制的路径。

启动 MongoDB

  1. 打开 命令提示符(或 PowerShell)。
  2. 运行以下命令以启动 MongoDB 服务:
    1
    net start MongoDB
  3. 然后你可以在 命令行 中输入 mongo 命令进入 MongoDB shell 进行交互式操作。

验证安装

在命令行中输入 mongo,你应该会看到 MongoDB 的 shell 环境,显示类似如下的内容:

1
2
MongoDB shell version v6.0.4
connecting to: mongodb://127.0.0.1:27017

至此,MongoDB 已经成功安装并启动。


macOS

安装 Homebrew

首先,确保你已经安装了 Homebrew,它是 macOS 上一个非常流行的包管理器。

如果没有安装 Homebrew,可以在 终端 中运行以下命令进行安装:

1
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

安装完成后,可以运行以下命令确认 Homebrew 是否安装成功:

1
brew --version

安装 MongoDB

  1. 使用 Homebrew 安装 MongoDB。打开 终端,运行以下命令:
1
2
brew tap mongodb/brew
brew install mongodb-community@6.0

这将从 MongoDB 官方的 Homebrew tap 中安装 MongoDB。

启动 MongoDB

安装完成后,可以通过以下命令启动 MongoDB 服务:

1
brew services start mongodb/brew/mongodb-community

这会在后台启动 MongoDB 服务。

停止 MongoDB 服务

如果你需要停止 MongoDB 服务,可以运行以下命令:

1
brew services stop mongodb/brew/mongodb-community

验证安装

  1. 打开 终端,运行以下命令启动 MongoDB shell:
1
mongo
  1. 如果 MongoDB 启动成功,你会看到类似以下内容:
1
2
MongoDB shell version v6.0.4
connecting to: mongodb://127.0.0.1:27017

常见问题与排查

MongoDB 服务未启动

  • Windows 上,如果 MongoDB 未作为服务启动,可以尝试手动启动 MongoDB 服务。运行命令:
    1
    net start MongoDB
  • macOS 上,如果服务未启动,可以尝试使用以下命令手动启动:
    1
    brew services start mongodb/brew/mongodb-community

连接失败

  • 确认 MongoDB 服务是否正在运行,可以通过以下命令检查:
    • Windows:
      1
      netstat -ano | findstr 27017
    • macOS:
      1
      ps aux | grep mongod

如果服务未启动,可以尝试重启 MongoDB 服务。

MongoDB 配置文件

  • WindowsmacOS 都有默认的 MongoDB 配置文件,通常位于:
    • WindowsC:\Program Files\MongoDB\Server\<version>\bin\mongod.cfg
    • macOS/usr/local/etc/mongod.conf

你可以根据需要修改配置文件,例如修改数据存储路径、日志路径等。


总结

  • Windows 安装 MongoDB 需要使用 MSI 安装包,然后配置环境变量和启动 MongoDB 服务。
  • macOS 安装 MongoDB 最方便的方法是通过 Homebrew 安装,然后通过命令管理 MongoDB 服务。

基本概念

数据库(Database)

数据库是 MongoDB 中的顶级数据结构。每个数据库包含若干集合(Collection)。MongoDB 默认有一个名为 test 的数据库。

集合(Collection)

集合类似于关系型数据库中的表。集合由多个文档组成。一个集合中的文档可以拥有不同的字段。

文档(Document)

文档是 MongoDB 存储数据的基本单位。它类似于 JSON 格式,使用键值对的方式存储数据。每个文档有一个 _id 字段,作为唯一标识符。

1
2
3
4
5
6
{
"_id": ObjectId("507f1f77bcf86cd799439011"),
"name": "John Doe",
"age": 30,
"email": "johndoe@example.com"
}

BSON

BSON(Binary JSON)是 MongoDB 使用的一种数据格式,类似 JSON,但支持更多的数据类型,如二进制数据、日期等。


MongoDB 数据库操作

创建和切换数据库

  • 切换到数据库(如果数据库不存在,则会创建):
    1
    use myDatabase

显示所有数据库

1
show dbs

删除数据库

1
db.dropDatabase()

查看当前数据库

1
db

MongoDB 查询操作

插入文档

插入单个文档:

1
2
3
4
5
db.users.insertOne({
name: "Alice",
age: 28,
email: "alice@example.com"
})

插入多个文档:

1
2
3
4
db.users.insertMany([
{ name: "Bob", age: 35, email: "bob@example.com" },
{ name: "Charlie", age: 40, email: "charlie@example.com" }
])

查询文档

查询所有文档:

1
db.users.find()

查询符合条件的文档:

1
db.users.find({ age: { $gt: 30 } })

查询并限制返回的字段:

1
db.users.find({ age: { $gt: 30 } }, { name: 1, email: 1 })

查询一个文档:

1
db.users.findOne({ name: "Alice" })

更新文档

更新单个文档:

1
2
3
4
db.users.updateOne(
{ name: "Alice" }, // 查询条件
{ $set: { age: 29 } } // 更新操作
)

更新多个文档:

1
2
3
4
db.users.updateMany(
{ age: { $gt: 30 } }, // 查询条件
{ $set: { status: "senior" } } // 更新操作
)

替换文档:

1
2
3
4
db.users.replaceOne(
{ name: "Bob" },
{ name: "Bob", age: 36, email: "bob_new@example.com" }
)

删除文档

删除单个文档:

1
db.users.deleteOne({ name: "Alice" })

删除多个文档:

1
db.users.deleteMany({ age: { $lt: 30 } })

MongoDB 索引与优化

创建索引

创建单字段索引:

1
db.users.createIndex({ name: 1 })

创建复合索引:

1
db.users.createIndex({ name: 1, age: -1 })

6.2 查看索引

1
db.users.getIndexes()

删除索引

1
db.users.dropIndex("name_1")

索引优化

  • 使用索引可以加速查询,避免全表扫描。
  • MongoDB 支持多种类型的索引,如哈希索引、文本索引、地理空间索引等。

MongoDB 聚合操作

MongoDB 提供强大的聚合框架,可以进行复杂的数据分析操作。

聚合管道

1
2
3
4
db.orders.aggregate([
{ $match: { status: "A" } },
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } }
])
  • $match: 用于过滤文档。
  • $group: 用于分组数据。
  • $sum: 用于计算总和。

MongoDB 数据备份与恢复

备份数据

使用 mongodump 命令备份数据库:

1
mongodump --db myDatabase --out /path/to/backup

恢复数据

使用 mongorestore 恢复数据:

1
mongorestore --db myDatabase /path/to/backup/myDatabase

MongoDB 安全与权限管理

MongoDB 提供了角色和权限控制功能来保护数据安全。

启用认证

修改 mongod.conf 配置文件,启用认证:

1
2
3
4
security:
authorization

: "enabled"

重启 MongoDB:

1
sudo systemctl restart mongod

创建用户

1
2
3
4
5
6
use admin
db.createUser({
user: "myAdmin",
pwd: "password",
roles: [{ role: "root", db: "admin" }]
})

MongoDB 性能优化

查询优化

  • 使用索引优化查询。
  • 使用 explain 了解查询执行计划。
1
db.users.find({ name: "Alice" }).explain("executionStats")

聚合优化

  • 使用 allowDiskUse 选项来处理大量数据:
    1
    db.orders.aggregate([{ $match: { status: "A" } }], { allowDiskUse: true })

MongoDB 常见问题与排查

MongoDB 连接问题

  • 确认 MongoDB 服务是否正在运行。
  • 检查防火墙设置,确保 MongoDB 端口(默认是 27017)开放。

性能问题

  • 使用 mongotopmongostat 命令检查数据库性能。
  • 分析慢查询,创建合适的索引。

在nodejs中使用mongodb

安装依赖

首先,在你的项目中安装所需的 npm 包:

1
2
npm init -y
npm install express mongoose
  • express 是一个 Web 框架,用于快速构建 HTTP 服务器。
  • mongoose 是 MongoDB 的 ODM(对象文档映射)库,它为 MongoDB 提供了一个更高层次的抽象,方便操作数据。

mongoose 文档: https://mongoosejs.com/docs/validation.html

配置 MongoDB 连接

app.jsserver.js 中,配置 Mongoose 连接 MongoDB 数据库。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const express = require('express')
const mongoose = require('mongoose')

// 创建 Express 应用
const app = express()

// 连接 MongoDB 数据库
mongoose.connect('mongodb://localhost:27017/mydb', { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log('MongoDB connected'))
.catch((err) => console.log('MongoDB connection error:', err))

// 中间件
app.use(express.json()) // 解析请求体中的 JSON 数据

// 启动服务器
const PORT = process.env.PORT || 3000
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`)
})

在 Mongoose 5.x 版本中,这两个选项可以用来处理 MongoDB 连接字符串的解析和现代化的拓扑管理。但在 Mongoose 6.x 版本中,这些选项的默认值已经更新为 true
如果你正在使用 Mongoose 6.x 或更高版本,建议直接省略这两个选项(useNewUrlParser 和 useUnifiedTopology),连接代码可以简化为:

1
2
3
4
5
const mongoose = require('mongoose')

mongoose.connect('mongodb://localhost:27017/mydatabase')
.then(() => console.log('MongoDB connected'))
.catch(err => console.error('MongoDB connection error:', err))

在这个例子中:

  • mongoose.connect() 用于连接 MongoDB 数据库,mongodb://localhost:27017/mydb 是连接字符串,表示连接到本地 MongoDB 实例中的 mydb 数据库。
  • useNewUrlParseruseUnifiedTopology 是 Mongoose 连接的配置选项,推荐开启以避免警告。

创建 Schema 和 Model

MongoDB 是一个无模式的数据库,但通过 Mongoose,你可以定义一个 Schema 来规范文档的结构。然后,使用 Model 来进行数据操作。

在你的项目中创建一个 models 目录,并创建一个 User.js 文件,定义一个简单的用户模型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// models/User.js
const mongoose = require('mongoose')

// 定义 Schema
const userSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
age: { type: Number, required: true },
})

// 创建 Model
const User = mongoose.model('User', userSchema)

module.exports = User

说明:

  • mongoose.Schema() 用于定义文档的结构(Schema),其中 name, email, age 是字段,每个字段都可以指定数据类型、是否为必填、是否唯一等。
  • mongoose.model() 用于创建模型,模型是与 MongoDB 中的集合(Collection)交互的接口。

Express 使用 MongoDB

现在,我们可以在 Express 路由中使用 Mongoose 模型来执行数据库操作。例如,创建用户、获取用户、更新用户和删除用户。

创建用户 API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// routes/user.js
const express = require('express')
const User = require('../models/User')
const router = express.Router()

// 创建用户
router.post('/users', async (req, res) => {
const { name, email, age } = req.body

try {
// 创建新的 User 实例
const user = new User({ name, email, age })

// 保存到数据库
await user.save()

// 返回响应
res.status(201).json(user)
} catch (err) {
res.status(400).json({ error: err.message })
}
})

module.exports = router

在上面的代码中:

  • router.post('/users') 处理客户端发送到 /users 路径的 POST 请求。
  • 使用 User 模型的 save() 方法保存数据到 MongoDB。

获取所有用户 API

1
2
3
4
5
6
7
8
9
// routes/user.js
router.get('/users', async (req, res) => {
try {
const users = await User.find() // 查询所有用户
res.status(200).json(users)
} catch (err) {
res.status(400).json({ error: err.message })
}
})

获取单个用户 API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// routes/user.js
router.get('/users/:id', async (req, res) => {
const { id } = req.params

try {
const user = await User.findById(id) // 根据 ID 查询用户
if (!user) {
return res.status(404).json({ error: 'User not found' })
}
res.status(200).json(user)
} catch (err) {
res.status(400).json({ error: err.message })
}
})

更新用户 API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// routes/user.js
router.put('/users/:id', async (req, res) => {
const { id } = req.params
const { name, email, age } = req.body

try {
const user = await User.findByIdAndUpdate(id, { name, email, age }, { new: true })
if (!user) {
return res.status(404).json({ error: 'User not found' })
}
res.status(200).json(user)
} catch (err) {
res.status(400).json({ error: err.message })
}
})

删除用户 API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// routes/user.js
router.delete('/users/:id', async (req, res) => {
const { id } = req.params

try {
const user = await User.findByIdAndDelete(id)
if (!user) {
return res.status(404).json({ error: 'User not found' })
}
res.status(200).json({ message: 'User deleted successfully' })
} catch (err) {
res.status(400).json({ error: err.message })
}
})

将路由集成到主应用中

将创建的路由文件集成到 app.jsserver.js 文件中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// app.js
const express = require('express')
const mongoose = require('mongoose')
const userRoutes = require('./routes/user')

const app = express()

// 连接到 MongoDB
mongoose.connect('mongodb://localhost:27017/mydb', { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log('MongoDB connected'))
.catch((err) => console.log('MongoDB connection error:', err))

// 中间件
app.use(express.json()) // 解析请求体中的 JSON 数据

// 路由
app.use('/api', userRoutes)

// 启动服务器
const PORT = process.env.PORT || 3000
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`)
})

说明:

  • app.use('/api', userRoutes):将用户相关的路由挂载到 /api 路径下,例如 POST /api/usersGET /api/users 等。

启动应用

在终端中运行以下命令启动应用:

1
node app.js

服务器会启动并监听 3000 端口,通过 Postman 或其他工具测试接口。

示例:

  • POST /api/users 创建用户
  • GET /api/users 获取所有用户
  • GET /api/users/:id 获取指定 ID 的用户
  • PUT /api/users/:id 更新指定 ID 的用户
  • DELETE /api/users/:id 删除指定 ID 的用户

更多 Mongoose 的高级用法(如数据验证、引用、聚合等),参考 Mongoose 官方文档