MongoDB 完全指南
目录
- [MongoDB 概述](#MongoDB 概述)
- 安装与配置
- 基础概念
- [CRUD 操作](#CRUD 操作)
- 查询操作符
- 索引
- 聚合框架
- 数据建模
- 事务
- 复制集
- 分片
- 安全配置
- 性能优化
- [Java 集成](#Java 集成)
- 实战案例
1. MongoDB 概述
1.1 什么是 MongoDB
MongoDB 是一个基于分布式文件存储的开源 NoSQL 数据库,使用 BSON(类 JSON)格式存储数据,具有高性能、高可用性和易扩展性。
1.2 主要特点
复制代码
MongoDB 特点:
├── 文档型数据库 - 使用 BSON 格式
├── 灵活的模式 - 无需预定义结构
├── 高性能 - 支持索引和内存映射
├── 高可用 - 复制集自动故障转移
├── 水平扩展 - 分片集群
├── 丰富的查询 - 支持聚合、全文搜索
└── 地理空间 - 支持地理位置查询
1.3 适用场景
复制代码
适合场景:
├── 内容管理系统
├── 实时分析
├── 物联网数据
├── 移动应用后端
├── 游戏数据
└── 日志存储
不适合场景:
├── 需要复杂事务的场景
├── 高度关联的数据
└── 需要严格一致性的金融系统
1.4 MongoDB vs MySQL
| 特性 |
MongoDB |
MySQL |
| 数据模型 |
文档(BSON) |
表(行和列) |
| 模式 |
灵活 |
固定 |
| 关联 |
嵌入/引用 |
JOIN |
| 事务 |
支持(4.0+) |
完整支持 |
| 扩展 |
水平扩展 |
垂直扩展 |
| 查询语言 |
MQL |
SQL |
2. 安装与配置
2.1 Linux 安装
bash
复制代码
# Ubuntu
wget -qO - https://www.mongodb.org/static/pgp/server-7.0.asc | sudo apt-key add -
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
sudo apt update
sudo apt install -y mongodb-org
# 启动服务
sudo systemctl start mongod
sudo systemctl enable mongod
sudo systemctl status mongod
2.2 macOS 安装
bash
复制代码
# 使用 Homebrew
brew tap mongodb/brew
brew install mongodb-community
# 启动服务
brew services start mongodb-community
2.3 Docker 安装
bash
复制代码
# 拉取镜像
docker pull mongo:latest
# 运行容器
docker run -d \
--name mongodb \
-p 27017:27017 \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=admin123 \
-v mongodb_data:/data/db \
mongo:latest
# 进入容器
docker exec -it mongodb mongosh
2.4 配置文件
yaml
复制代码
# /etc/mongod.conf
storage:
dbPath: /var/lib/mongodb
journal:
enabled: true
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
net:
port: 27017
bindIp: 127.0.0.1
security:
authorization: enabled
replication:
replSetName: rs0
2.5 常用命令
bash
复制代码
# 连接数据库
mongosh
mongosh "mongodb://localhost:27017"
mongosh "mongodb://user:password@localhost:27017/dbname"
# 服务管理
sudo systemctl start mongod
sudo systemctl stop mongod
sudo systemctl restart mongod
# 查看状态
mongosh --eval "db.serverStatus()"
3. 基础概念
3.1 术语对比
| SQL 术语 |
MongoDB 术语 |
| Database |
Database |
| Table |
Collection |
| Row |
Document |
| Column |
Field |
| Index |
Index |
| Primary Key |
_id |
| JOIN |
$lookup / 嵌入 |
3.2 数据库操作
javascript
复制代码
// 显示所有数据库
show dbs
// 切换/创建数据库
use mydb
// 显示当前数据库
db
// 删除数据库
db.dropDatabase()
// 查看数据库状态
db.stats()
3.3 集合操作
javascript
复制代码
// 显示所有集合
show collections
// 创建集合
db.createCollection("users")
// 创建带选项的集合
db.createCollection("logs", {
capped: true, // 固定大小集合
size: 10485760, // 10MB
max: 5000 // 最多 5000 个文档
})
// 删除集合
db.users.drop()
// 重命名集合
db.users.renameCollection("members")
3.4 文档结构
javascript
复制代码
// BSON 文档示例
{
_id: ObjectId("507f1f77bcf86cd799439011"),
name: "张三",
age: 25,
email: "zhangsan@example.com",
tags: ["developer", "mongodb"],
address: {
city: "北京",
street: "朝阳区"
},
createdAt: ISODate("2024-01-15T08:00:00Z")
}
3.5 数据类型
javascript
复制代码
// 常用数据类型
String // 字符串
Number // 数字(整数或浮点数)
Boolean // 布尔值
Date // 日期
Array // 数组
Object // 嵌入文档
ObjectId // 文档 ID
Null // 空值
Binary // 二进制数据
Decimal128 // 高精度小数
// 示例
{
string: "hello",
number: 123,
float: 3.14,
boolean: true,
date: new Date(),
array: [1, 2, 3],
object: { key: "value" },
objectId: ObjectId(),
null: null,
decimal: NumberDecimal("9.99")
}
4. CRUD 操作
4.1 插入文档
javascript
复制代码
// 插入单个文档
db.users.insertOne({
name: "张三",
age: 25,
email: "zhangsan@example.com"
})
// 插入多个文档
db.users.insertMany([
{ name: "李四", age: 30, email: "lisi@example.com" },
{ name: "王五", age: 28, email: "wangwu@example.com" }
])
// 插入时指定 _id
db.users.insertOne({
_id: "user001",
name: "赵六",
age: 35
})
4.2 查询文档
javascript
复制代码
// 查询所有文档
db.users.find()
// 格式化输出
db.users.find().pretty()
// 查询单个文档
db.users.findOne({ name: "张三" })
// 条件查询
db.users.find({ age: 25 })
db.users.find({ age: { $gt: 25 } }) // 大于 25
// 指定返回字段
db.users.find({}, { name: 1, age: 1, _id: 0 })
// 限制和跳过
db.users.find().limit(10)
db.users.find().skip(5).limit(10)
// 排序
db.users.find().sort({ age: 1 }) // 升序
db.users.find().sort({ age: -1 }) // 降序
// 计数
db.users.countDocuments({ age: { $gt: 25 } })
// 去重
db.users.distinct("age")
4.3 更新文档
javascript
复制代码
// 更新单个文档
db.users.updateOne(
{ name: "张三" },
{ $set: { age: 26 } }
)
// 更新多个文档
db.users.updateMany(
{ age: { $lt: 30 } },
{ $set: { status: "young" } }
)
// 替换文档
db.users.replaceOne(
{ name: "张三" },
{ name: "张三", age: 27, email: "new@example.com" }
)
// 更新或插入(upsert)
db.users.updateOne(
{ name: "新用户" },
{ $set: { age: 20 } },
{ upsert: true }
)
// 更新操作符
db.users.updateOne(
{ name: "张三" },
{
$set: { age: 28 }, // 设置字段
$unset: { temp: "" }, // 删除字段
$inc: { score: 10 }, // 增加值
$push: { tags: "new" }, // 数组添加
$pull: { tags: "old" }, // 数组删除
$addToSet: { tags: "unique" } // 数组添加(去重)
}
)
4.4 删除文档
javascript
复制代码
// 删除单个文档
db.users.deleteOne({ name: "张三" })
// 删除多个文档
db.users.deleteMany({ age: { $lt: 18 } })
// 删除所有文档
db.users.deleteMany({})
// 查找并删除
db.users.findOneAndDelete({ name: "张三" })
4.5 批量操作
javascript
复制代码
// 批量写入
db.users.bulkWrite([
{ insertOne: { document: { name: "A", age: 20 } } },
{ updateOne: { filter: { name: "B" }, update: { $set: { age: 25 } } } },
{ deleteOne: { filter: { name: "C" } } }
])
5. 查询操作符
5.1 比较操作符
javascript
复制代码
// $eq - 等于
db.users.find({ age: { $eq: 25 } })
// $ne - 不等于
db.users.find({ age: { $ne: 25 } })
// $gt - 大于
db.users.find({ age: { $gt: 25 } })
// $gte - 大于等于
db.users.find({ age: { $gte: 25 } })
// $lt - 小于
db.users.find({ age: { $lt: 25 } })
// $lte - 小于等于
db.users.find({ age: { $lte: 25 } })
// $in - 在数组中
db.users.find({ age: { $in: [20, 25, 30] } })
// $nin - 不在数组中
db.users.find({ age: { $nin: [20, 25, 30] } })
5.2 逻辑操作符
javascript
复制代码
// $and - 与
db.users.find({
$and: [
{ age: { $gte: 20 } },
{ age: { $lte: 30 } }
]
})
// 简写形式
db.users.find({ age: { $gte: 20, $lte: 30 } })
// $or - 或
db.users.find({
$or: [
{ age: { $lt: 20 } },
{ age: { $gt: 30 } }
]
})
// $not - 非
db.users.find({ age: { $not: { $gt: 25 } } })
// $nor - 都不
db.users.find({
$nor: [
{ age: { $lt: 20 } },
{ status: "inactive" }
]
})
5.3 元素操作符
javascript
复制代码
// $exists - 字段存在
db.users.find({ email: { $exists: true } })
// $type - 字段类型
db.users.find({ age: { $type: "number" } })
db.users.find({ age: { $type: 16 } }) // int32
5.4 数组操作符
javascript
复制代码
// $all - 包含所有元素
db.users.find({ tags: { $all: ["mongodb", "nodejs"] } })
// $elemMatch - 数组元素匹配
db.orders.find({
items: {
$elemMatch: {
product: "手机",
quantity: { $gt: 1 }
}
}
})
// $size - 数组大小
db.users.find({ tags: { $size: 3 } })
5.5 正则表达式
javascript
复制代码
// 正则匹配
db.users.find({ name: /^张/ })
db.users.find({ name: { $regex: "^张" } })
// 不区分大小写
db.users.find({ email: { $regex: "example", $options: "i" } })
5.6 投影操作符
javascript
复制代码
// $ - 返回匹配的数组元素
db.users.find(
{ "scores.subject": "math" },
{ "scores.$": 1 }
)
// $slice - 数组切片
db.users.find({}, { tags: { $slice: 2 } }) // 前 2 个
db.users.find({}, { tags: { $slice: -2 } }) // 后 2 个
db.users.find({}, { tags: { $slice: [1, 2] } }) // 跳过 1 个,取 2 个
6. 索引
6.1 索引类型
javascript
复制代码
// 单字段索引
db.users.createIndex({ name: 1 }) // 升序
db.users.createIndex({ age: -1 }) // 降序
// 复合索引
db.users.createIndex({ name: 1, age: -1 })
// 唯一索引
db.users.createIndex({ email: 1 }, { unique: true })
// 稀疏索引(只索引存在该字段的文档)
db.users.createIndex({ phone: 1 }, { sparse: true })
// TTL 索引(自动过期)
db.logs.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 })
// 文本索引
db.articles.createIndex({ title: "text", content: "text" })
// 地理空间索引
db.places.createIndex({ location: "2dsphere" })
// 哈希索引
db.users.createIndex({ name: "hashed" })
6.2 索引管理
javascript
复制代码
// 查看索引
db.users.getIndexes()
// 删除索引
db.users.dropIndex("name_1")
db.users.dropIndex({ name: 1 })
// 删除所有索引(除 _id)
db.users.dropIndexes()
// 重建索引
db.users.reIndex()
6.3 索引选项
javascript
复制代码
db.users.createIndex(
{ email: 1 },
{
unique: true, // 唯一索引
sparse: true, // 稀疏索引
background: true, // 后台创建
name: "email_unique", // 索引名称
partialFilterExpression: { age: { $gt: 18 } } // 部分索引
}
)
6.4 查询分析
javascript
复制代码
// 执行计划
db.users.find({ name: "张三" }).explain()
db.users.find({ name: "张三" }).explain("executionStats")
// 查看索引使用情况
db.users.aggregate([
{ $indexStats: {} }
])
7. 聚合框架
7.1 聚合管道
javascript
复制代码
db.orders.aggregate([
{ $match: { status: "completed" } },
{ $group: { _id: "$customerId", total: { $sum: "$amount" } } },
{ $sort: { total: -1 } },
{ $limit: 10 }
])
7.2 常用聚合阶段
javascript
复制代码
// $match - 过滤
{ $match: { status: "active" } }
// $project - 投影
{ $project: { name: 1, age: 1, _id: 0 } }
// $group - 分组
{ $group: { _id: "$category", count: { $sum: 1 } } }
// $sort - 排序
{ $sort: { createdAt: -1 } }
// $limit - 限制
{ $limit: 10 }
// $skip - 跳过
{ $skip: 20 }
// $unwind - 展开数组
{ $unwind: "$tags" }
// $lookup - 关联查询
{
$lookup: {
from: "orders",
localField: "_id",
foreignField: "userId",
as: "orders"
}
}
// $addFields - 添加字段
{ $addFields: { fullName: { $concat: ["$firstName", " ", "$lastName"] } } }
// $count - 计数
{ $count: "total" }
7.3 聚合操作符
javascript
复制代码
// 算术操作符
{ $add: ["$price", "$tax"] }
{ $subtract: ["$total", "$discount"] }
{ $multiply: ["$price", "$quantity"] }
{ $divide: ["$total", "$count"] }
// 字符串操作符
{ $concat: ["$firstName", " ", "$lastName"] }
{ $substr: ["$name", 0, 3] }
{ $toUpper: "$name" }
{ $toLower: "$email" }
// 日期操作符
{ $year: "$createdAt" }
{ $month: "$createdAt" }
{ $dayOfMonth: "$createdAt" }
{ $dateToString: { format: "%Y-%m-%d", date: "$createdAt" } }
// 条件操作符
{ $cond: { if: { $gte: ["$age", 18] }, then: "adult", else: "minor" } }
{ $ifNull: ["$nickname", "$name"] }
7.4 分组累加器
javascript
复制代码
db.orders.aggregate([
{
$group: {
_id: "$category",
count: { $sum: 1 },
totalAmount: { $sum: "$amount" },
avgAmount: { $avg: "$amount" },
minAmount: { $min: "$amount" },
maxAmount: { $max: "$amount" },
items: { $push: "$name" },
uniqueItems: { $addToSet: "$name" },
firstItem: { $first: "$name" },
lastItem: { $last: "$name" }
}
}
])
7.5 聚合示例
javascript
复制代码
// 统计每个用户的订单数和总金额
db.orders.aggregate([
{ $match: { status: "completed" } },
{
$group: {
_id: "$userId",
orderCount: { $sum: 1 },
totalAmount: { $sum: "$amount" }
}
},
{
$lookup: {
from: "users",
localField: "_id",
foreignField: "_id",
as: "user"
}
},
{ $unwind: "$user" },
{
$project: {
_id: 0,
userName: "$user.name",
orderCount: 1,
totalAmount: 1
}
},
{ $sort: { totalAmount: -1 } }
])
// 按月统计销售额
db.orders.aggregate([
{
$group: {
_id: {
year: { $year: "$createdAt" },
month: { $month: "$createdAt" }
},
totalSales: { $sum: "$amount" },
orderCount: { $sum: 1 }
}
},
{ $sort: { "_id.year": 1, "_id.month": 1 } }
])
8. 数据建模
8.1 嵌入式文档
javascript
复制代码
// 一对一关系 - 嵌入
{
_id: ObjectId("..."),
name: "张三",
address: {
city: "北京",
street: "朝阳区xxx街道",
zipCode: "100000"
}
}
// 一对多关系 - 嵌入(少量)
{
_id: ObjectId("..."),
title: "MongoDB 教程",
comments: [
{ user: "用户A", content: "很好", date: ISODate("...") },
{ user: "用户B", content: "不错", date: ISODate("...") }
]
}
8.2 引用式文档
javascript
复制代码
// 一对多关系 - 引用(大量)
// users 集合
{
_id: ObjectId("user1"),
name: "张三"
}
// orders 集合
{
_id: ObjectId("order1"),
userId: ObjectId("user1"),
amount: 100
}
// 查询时使用 $lookup
db.users.aggregate([
{
$lookup: {
from: "orders",
localField: "_id",
foreignField: "userId",
as: "orders"
}
}
])
8.3 设计原则
复制代码
嵌入适合:
├── 一对一关系
├── 一对少量关系
├── 数据经常一起读取
└── 子文档不需要单独访问
引用适合:
├── 一对多(大量)关系
├── 多对多关系
├── 数据需要独立访问
└── 数据更新频繁
8.4 模式设计模式
javascript
复制代码
// 1. 多态模式
{
type: "book",
title: "MongoDB 指南",
author: "张三",
pages: 500
}
{
type: "movie",
title: "MongoDB 纪录片",
director: "李四",
duration: 120
}
// 2. 属性模式
{
name: "产品A",
attributes: [
{ key: "color", value: "red" },
{ key: "size", value: "large" }
]
}
// 3. 桶模式(时序数据)
{
sensorId: "sensor001",
date: ISODate("2024-01-15"),
readings: [
{ time: "08:00", value: 25.5 },
{ time: "09:00", value: 26.0 }
]
}
9. 事务
9.1 单文档事务
javascript
复制代码
// MongoDB 保证单文档操作的原子性
db.accounts.updateOne(
{ _id: "account1" },
{
$inc: { balance: -100 },
$push: { transactions: { type: "withdraw", amount: 100 } }
}
)
9.2 多文档事务
javascript
复制代码
// 开启会话
const session = db.getMongo().startSession()
// 开始事务
session.startTransaction()
try {
const accounts = session.getDatabase("bank").accounts
// 转账操作
accounts.updateOne(
{ _id: "account1" },
{ $inc: { balance: -100 } },
{ session }
)
accounts.updateOne(
{ _id: "account2" },
{ $inc: { balance: 100 } },
{ session }
)
// 提交事务
session.commitTransaction()
} catch (error) {
// 回滚事务
session.abortTransaction()
throw error
} finally {
session.endSession()
}
9.3 事务选项
javascript
复制代码
session.startTransaction({
readConcern: { level: "snapshot" },
writeConcern: { w: "majority" },
readPreference: "primary"
})
10. 复制集
10.1 复制集概念
复制代码
复制集架构:
├── Primary(主节点)- 接收所有写操作
├── Secondary(从节点)- 复制主节点数据
└── Arbiter(仲裁节点)- 只参与选举
10.2 配置复制集
javascript
复制代码
// 初始化复制集
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "mongo1:27017" },
{ _id: 1, host: "mongo2:27017" },
{ _id: 2, host: "mongo3:27017" }
]
})
// 查看状态
rs.status()
// 查看配置
rs.conf()
// 添加节点
rs.add("mongo4:27017")
// 添加仲裁节点
rs.addArb("arbiter:27017")
// 移除节点
rs.remove("mongo4:27017")
10.3 读写分离
javascript
复制代码
// 连接字符串
mongodb://mongo1:27017,mongo2:27017,mongo3:27017/?replicaSet=rs0
// 读偏好设置
db.users.find().readPref("secondary")
db.users.find().readPref("secondaryPreferred")
db.users.find().readPref("nearest")
11. 分片
11.1 分片概念
复制代码
分片集群组件:
├── Shard(分片)- 存储数据子集
├── Config Server(配置服务器)- 存储元数据
└── Mongos(路由)- 查询路由
11.2 分片策略
javascript
复制代码
// 范围分片
sh.shardCollection("mydb.users", { age: 1 })
// 哈希分片
sh.shardCollection("mydb.users", { _id: "hashed" })
// 复合分片键
sh.shardCollection("mydb.orders", { userId: 1, orderId: 1 })
11.3 分片管理
javascript
复制代码
// 启用数据库分片
sh.enableSharding("mydb")
// 查看分片状态
sh.status()
// 添加分片
sh.addShard("shard1/mongo1:27017")
// 查看数据分布
db.users.getShardDistribution()
12. 安全配置
12.1 用户管理
javascript
复制代码
// 创建管理员
use admin
db.createUser({
user: "admin",
pwd: "admin123",
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" }
]
})
// 创建普通用户
use mydb
db.createUser({
user: "appuser",
pwd: "password",
roles: [
{ role: "readWrite", db: "mydb" }
]
})
// 查看用户
db.getUsers()
// 删除用户
db.dropUser("appuser")
// 修改密码
db.changeUserPassword("appuser", "newpassword")
12.2 内置角色
javascript
复制代码
// 数据库角色
read // 读取
readWrite // 读写
dbAdmin // 数据库管理
userAdmin // 用户管理
dbOwner // 数据库所有者
// 集群角色
clusterAdmin // 集群管理
clusterManager // 集群管理器
clusterMonitor // 集群监控
// 全局角色
readAnyDatabase
readWriteAnyDatabase
userAdminAnyDatabase
dbAdminAnyDatabase
root // 超级管理员
12.3 启用认证
yaml
复制代码
# mongod.conf
security:
authorization: enabled
bash
复制代码
# 使用认证连接
mongosh -u admin -p admin123 --authenticationDatabase admin
13. 性能优化
13.1 查询优化
javascript
复制代码
// 使用索引
db.users.createIndex({ name: 1 })
// 覆盖查询(只返回索引字段)
db.users.find({ name: "张三" }, { name: 1, _id: 0 })
// 限制返回字段
db.users.find({}, { name: 1, email: 1 })
// 使用 limit
db.users.find().limit(100)
// 避免 $where
// ❌ db.users.find({ $where: "this.age > 25" })
// ✅ db.users.find({ age: { $gt: 25 } })
13.2 写入优化
javascript
复制代码
// 批量写入
db.users.insertMany(documents, { ordered: false })
// 使用 bulkWrite
db.users.bulkWrite(operations, { ordered: false })
13.3 索引优化
javascript
复制代码
// 分析慢查询
db.setProfilingLevel(1, { slowms: 100 })
db.system.profile.find().sort({ ts: -1 }).limit(10)
// 查看索引使用
db.users.aggregate([{ $indexStats: {} }])
// 删除未使用的索引
db.users.dropIndex("unused_index")
13.4 配置优化
yaml
复制代码
# mongod.conf
storage:
wiredTiger:
engineConfig:
cacheSizeGB: 4
collectionConfig:
blockCompressor: snappy
14. Java 集成
14.1 添加依赖
xml
复制代码
<!-- MongoDB Driver -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>4.11.0</version>
</dependency>
<!-- Spring Data MongoDB -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
14.2 Spring Boot 配置
yaml
复制代码
# application.yml
spring:
data:
mongodb:
uri: mongodb://localhost:27017/mydb
# 或分开配置
host: localhost
port: 27017
database: mydb
username: user
password: password
authentication-database: admin
14.3 实体类
java
复制代码
@Document(collection = "users")
@Data
public class User {
@Id
private String id;
@Field("name")
@Indexed
private String name;
private Integer age;
@Indexed(unique = true)
private String email;
private List<String> tags;
private Address address;
@CreatedDate
private LocalDateTime createdAt;
@LastModifiedDate
private LocalDateTime updatedAt;
}
@Data
public class Address {
private String city;
private String street;
private String zipCode;
}
14.4 Repository
java
复制代码
@Repository
public interface UserRepository extends MongoRepository<User, String> {
// 根据名称查询
List<User> findByName(String name);
// 根据年龄范围查询
List<User> findByAgeBetween(Integer minAge, Integer maxAge);
// 根据标签查询
List<User> findByTagsContaining(String tag);
// 自定义查询
@Query("{ 'age': { $gt: ?0 } }")
List<User> findByAgeGreaterThan(Integer age);
// 分页查询
Page<User> findByAgeGreaterThan(Integer age, Pageable pageable);
// 存在性检查
boolean existsByEmail(String email);
// 删除
void deleteByName(String name);
}
14.5 MongoTemplate
java
复制代码
@Service
public class UserService {
@Autowired
private MongoTemplate mongoTemplate;
// 插入
public User save(User user) {
return mongoTemplate.save(user);
}
// 查询
public List<User> findByAge(Integer age) {
Query query = new Query(Criteria.where("age").is(age));
return mongoTemplate.find(query, User.class);
}
// 复杂查询
public List<User> findByConditions(String name, Integer minAge, Integer maxAge) {
Criteria criteria = new Criteria();
if (name != null) {
criteria.and("name").regex(name, "i");
}
if (minAge != null) {
criteria.and("age").gte(minAge);
}
if (maxAge != null) {
criteria.and("age").lte(maxAge);
}
Query query = new Query(criteria);
return mongoTemplate.find(query, User.class);
}
// 更新
public void updateAge(String id, Integer age) {
Query query = new Query(Criteria.where("_id").is(id));
Update update = new Update().set("age", age);
mongoTemplate.updateFirst(query, update, User.class);
}
// 聚合
public List<Map> countByAge() {
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.group("age").count().as("count"),
Aggregation.sort(Sort.Direction.DESC, "count")
);
AggregationResults<Map> results = mongoTemplate.aggregate(
aggregation, "users", Map.class);
return results.getMappedResults();
}
// 删除
public void delete(String id) {
Query query = new Query(Criteria.where("_id").is(id));
mongoTemplate.remove(query, User.class);
}
}
15. 实战案例
15.1 博客系统数据模型
javascript
复制代码
// 用户集合
{
_id: ObjectId("..."),
username: "zhangsan",
email: "zhangsan@example.com",
password: "hashed_password",
profile: {
nickname: "张三",
avatar: "https://...",
bio: "技术爱好者"
},
createdAt: ISODate("...")
}
// 文章集合
{
_id: ObjectId("..."),
title: "MongoDB 入门教程",
slug: "mongodb-tutorial",
content: "文章内容...",
summary: "摘要...",
author: ObjectId("user_id"),
category: "技术",
tags: ["mongodb", "database", "nosql"],
status: "published",
viewCount: 1000,
likeCount: 50,
commentCount: 10,
createdAt: ISODate("..."),
updatedAt: ISODate("..."),
publishedAt: ISODate("...")
}
// 评论集合
{
_id: ObjectId("..."),
articleId: ObjectId("article_id"),
userId: ObjectId("user_id"),
content: "评论内容",
parentId: null, // 回复时指向父评论
createdAt: ISODate("...")
}
15.2 电商系统数据模型
javascript
复制代码
// 商品集合
{
_id: ObjectId("..."),
name: "iPhone 15",
description: "最新款苹果手机",
price: NumberDecimal("7999.00"),
originalPrice: NumberDecimal("8999.00"),
stock: 100,
category: ["电子产品", "手机"],
brand: "Apple",
images: ["url1", "url2"],
specifications: [
{ key: "颜色", value: "黑色" },
{ key: "存储", value: "256GB" }
],
status: "on_sale",
salesCount: 500,
createdAt: ISODate("...")
}
// 订单集合
{
_id: ObjectId("..."),
orderNo: "202401150001",
userId: ObjectId("user_id"),
items: [
{
productId: ObjectId("product_id"),
name: "iPhone 15",
price: NumberDecimal("7999.00"),
quantity: 1,
subtotal: NumberDecimal("7999.00")
}
],
totalAmount: NumberDecimal("7999.00"),
status: "paid",
shippingAddress: {
name: "张三",
phone: "13800138000",
province: "北京市",
city: "北京市",
district: "朝阳区",
address: "xxx街道xxx号"
},
payment: {
method: "alipay",
transactionId: "...",
paidAt: ISODate("...")
},
createdAt: ISODate("..."),
updatedAt: ISODate("...")
}
15.3 常用查询示例
javascript
复制代码
// 1. 分页查询文章
db.articles.find({ status: "published" })
.sort({ publishedAt: -1 })
.skip(0)
.limit(10)
// 2. 全文搜索
db.articles.createIndex({ title: "text", content: "text" })
db.articles.find({ $text: { $search: "MongoDB 教程" } })
// 3. 统计每个分类的文章数
db.articles.aggregate([
{ $match: { status: "published" } },
{ $group: { _id: "$category", count: { $sum: 1 } } },
{ $sort: { count: -1 } }
])
// 4. 获取热门文章
db.articles.find({ status: "published" })
.sort({ viewCount: -1 })
.limit(10)
// 5. 用户订单统计
db.orders.aggregate([
{ $match: { userId: ObjectId("user_id") } },
{
$group: {
_id: null,
totalOrders: { $sum: 1 },
totalAmount: { $sum: "$totalAmount" }
}
}
])
// 6. 月度销售报表
db.orders.aggregate([
{ $match: { status: { $in: ["paid", "shipped", "completed"] } } },
{
$group: {
_id: {
year: { $year: "$createdAt" },
month: { $month: "$createdAt" }
},
orderCount: { $sum: 1 },
totalSales: { $sum: "$totalAmount" }
}
},
{ $sort: { "_id.year": -1, "_id.month": -1 } }
])
附录:常用命令速查
数据库操作
javascript
复制代码
show dbs // 显示数据库
use dbname // 切换数据库
db.dropDatabase() // 删除数据库
集合操作
javascript
复制代码
show collections // 显示集合
db.createCollection("name") // 创建集合
db.collection.drop() // 删除集合
CRUD
javascript
复制代码
db.col.insertOne({}) // 插入单个
db.col.insertMany([]) // 插入多个
db.col.find({}) // 查询
db.col.findOne({}) // 查询单个
db.col.updateOne({}, {}) // 更新单个
db.col.updateMany({}, {}) // 更新多个
db.col.deleteOne({}) // 删除单个
db.col.deleteMany({}) // 删除多个
索引
javascript
复制代码
db.col.createIndex({}) // 创建索引
db.col.getIndexes() // 查看索引
db.col.dropIndex("name") // 删除索引
聚合
javascript
复制代码
db.col.aggregate([]) // 聚合查询
db.col.countDocuments({}) // 计数
db.col.distinct("field") // 去重