MongoDB 完全指南

MongoDB 完全指南

目录

  1. [MongoDB 概述](#MongoDB 概述)
  2. 安装与配置
  3. 基础概念
  4. [CRUD 操作](#CRUD 操作)
  5. 查询操作符
  6. 索引
  7. 聚合框架
  8. 数据建模
  9. 事务
  10. 复制集
  11. 分片
  12. 安全配置
  13. 性能优化
  14. [Java 集成](#Java 集成)
  15. 实战案例

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")    // 去重
相关推荐
山岚的运维笔记1 小时前
SQL Server笔记 -- 第34章:cross apply
服务器·前端·数据库·笔记·sql·microsoft·sqlserver
文档搬运工1 小时前
OS的load average很高
数据库
爬山算法1 小时前
MongoDB(3)什么是文档(Document)?
数据库·mongodb
爬山算法1 小时前
MongoDB(9)什么是MongoDB的副本集(Replica Set)?
数据库·mongodb
thginWalker2 小时前
实战篇 & 结束篇
数据库
William_cl2 小时前
【EFCore 从入门到避坑】模型映射全解析:数据注解 VS FluentAPI(附实战代码 + 踩坑指南)
数据库·oracle
ghie90902 小时前
基于MATLAB的指纹定位算法仿真实现
数据库·算法·matlab
知识分享小能手2 小时前
SQL Server 2019入门学习教程,从入门到精通,Transact-SQL数据的更新 —语法详解与实战案例(SQL Server 2019)(10)
数据库·学习·sqlserver
松涛和鸣2 小时前
75、 IMX6ULL LM75温度传感器I2C驱动开发
java·linux·数据库·驱动开发·python