Skip to content

第四章 索引与聚合 v1.0 ​

一、索引 ​

索引是特殊的数据结构,存储集合中一小部分数据集的有序表示,用于提高查询效率。

1.创建索引 ​

javascript
// 创建单字段索引(1为升序,-1为降序)
db.users.createIndex({ name: 1 })

// 创建唯一索引
db.users.createIndex({ email: 1 }, { unique: true })

// 创建复合索引
db.users.createIndex({ name: 1, age: -1 })

// 创建文本索引(用于全文搜索)
db.articles.createIndex({ title: "text", content: "text" })

2.查看索引 ​

javascript
// 查看集合的所有索引
db.users.getIndexes()

// 查看索引大小
db.users.totalIndexSize()

3.删除索引 ​

javascript
// 删除指定索引
db.users.dropIndex({ name: 1 })

// 删除所有索引(_id索引除外)
db.users.dropIndexes()

4.索引类型 ​

类型说明适用场景
单字段索引单个字段的升序/降序最常见的查询优化
复合索引多个字段组合多条件查询
唯一索引确保字段值唯一邮箱、用户名等
文本索引全文搜索文章内容搜索
哈希索引基于哈希值等值查询、分片
TTL索引自动过期删除日志、Session
多键索引数组字段数组类型的字段

二、聚合(Aggregation) ​

聚合管道将文档通过多个阶段(Stage)进行处理,每个阶段的输出作为下一个阶段的输入。

1.常用阶段 ​

javascript
// $match:过滤文档(类似find)
db.users.aggregate([{ $match: { age: { $gte: 18 } } }])

// $group:分组统计
db.users.aggregate([
    { $group: { _id: "$city", count: { $sum: 1 }, avgAge: { $avg: "$age" } } }
])

// $sort:排序
db.users.aggregate([{ $sort: { age: -1 } }])

// $limit / $skip:分页
db.users.aggregate([{ $skip: 10 }, { $limit: 5 }])

// $project:字段投影
db.users.aggregate([
    { $project: { name: 1, age: 1, isAdult: { $gte: ["$age", 18] } } }
])

// $lookup:关联查询(类似SQL的JOIN)
db.orders.aggregate([
    {
        $lookup: {
            from: "users",
            localField: "userId",
            foreignField: "_id",
            as: "user"
        }
    }
])

2.常用累加器 ​

操作符说明示例
$sum求和{ $sum: "$price" }
$avg平均值{ $avg: "$score" }
$max最大值{ $max: "$age" }
$min最小值{ $min: "$age" }
$push收集为数组{ $push: "$name" }
$first第一个值{ $first: "$name" }
$last最后一个值{ $last: "$name" }
$addToSet去重收集{ $addToSet: "$tag" }

3.聚合示例 ​

javascript
// 按城市统计用户数和平均年龄,按用户数降序排列
db.users.aggregate([
    { $group: { _id: "$city", count: { $sum: 1 }, avgAge: { $avg: "$age" } } },
    { $sort: { count: -1 } }
])

// 统计每个用户的订单总金额
db.orders.aggregate([
    { $group: { _id: "$userId", totalAmount: { $sum: "$amount" } } },
    { $lookup: { from: "users", localField: "_id", foreignField: "_id", as: "user" } },
    { $unwind: "$user" },
    { $project: { userName: "$user.name", totalAmount: 1 } }
])