简述MongoDB聚合?

参考回答

MongoDB 的聚合操作是一种强大的数据处理方式,用于对集合中的文档执行复杂的计算和转换。它通过 aggregate() 方法实现,可以完成分组、过滤、排序、计算等功能,类似于 SQL 中的 GROUP BYHAVING

聚合操作的核心是 聚合管道,它将多个数据处理阶段按顺序组合,每个阶段对输入数据进行操作,并将结果传递给下一个阶段。


详细讲解与拓展

1. 聚合的基本语法

db.collection.aggregate([ { stage1 }, { stage2 }, ... ])
JavaScript

每个 { stage } 表示一个数据处理阶段,常见的阶段包括:
$match:过滤文档,相当于 SQL 中的 WHERE
$group:按字段分组并计算聚合结果,相当于 SQL 中的 GROUP BY
$project:指定返回字段,相当于 SQL 中的 SELECT
$sort:排序结果,相当于 SQL 中的 ORDER BY
$limit:限制结果数量,相当于 SQL 中的 LIMIT
$skip:跳过指定数量的文档,相当于分页操作。


2. 常见聚合阶段

  1. $match:过滤文档
    • 用于筛选符合条件的文档,通常是聚合的第一阶段。
    • 示例:查询年龄大于 30 的用户:
      db.users.aggregate([
       { match: { age: {gt: 30 } } }
      ])
      
      JavaScript
  2. $group:分组并计算
    • 用于将文档分组,并对每组数据进行统计或计算。
    • 示例:按城市分组,并计算每个城市的用户数量:
      db.users.aggregate([
       { group: { _id: "city", count: { $sum: 1 } } }
      ])
      
      JavaScript
  3. $project:字段投影
    • 用于选择返回的字段,并支持对字段进行重命名或计算。
    • 示例:只返回用户的名字和年龄:
      db.users.aggregate([
       { $project: { name: 1, age: 1, _id: 0 } }
      ])
      
      JavaScript
  4. $sort:排序
    • 用于对文档排序。
    • 示例:按年龄降序排序:
      db.users.aggregate([
       { $sort: { age: -1 } }
      ])
      
      JavaScript
  5. $limit$skip:分页
    • 示例:查询前 5 条记录:
      db.users.aggregate([
       { $limit: 5 }
      ])
      
      JavaScript

3. 示例:综合应用

假设集合包含以下文档:

[
    { "name": "Alice", "age": 25, "city": "New York" },
    { "name": "Bob", "age": 30, "city": "Chicago" },
    { "name": "Charlie", "age": 35, "city": "New York" },
    { "name": "David", "age": 40, "city": "Chicago" }
]
JSON

需求:统计每个城市中年龄大于 30 的用户数量,并按数量降序排序。

聚合管道

db.users.aggregate([
    { match: { age: {gt: 30 } } }, // 过滤年龄大于 30 的用户
    { group: { _id: "city", count: { sum: 1 } } }, // 按城市分组并统计数量
    {sort: { count: -1 } } // 按数量降序排序
])
JavaScript

结果

[
    { "_id": "Chicago", "count": 2 },
    { "_id": "New York", "count": 1 }
]
JSON

4. 常用聚合操作符

操作符 功能 示例
$sum 求和 { count: { $sum: 1 } }
$avg 平均值 { avgAge: { avg: "age" } }
$min 最小值 { minAge: { min: "age" } }
$max 最大值 { maxAge: { max: "age" } }
$push 将字段值数组化 { users: { push: "name" } }
$first 返回分组中的第一条记录 { firstUser: { first: "name" } }
$last 返回分组中的最后一条记录 { lastUser: { last: "name" } }

5. 聚合性能优化

  1. 尽量使用索引
    • $match 阶段利用索引,可以显著提高性能。
    • 示例:为 age 字段创建索引:
      db.users.createIndex({ age: 1 })
      
      JavaScript
  2. 限制返回数据量
    • 使用 $limit$project 限制返回字段和文档数量,减少内存使用。
  3. 避免大数据排序
    • 如果可能,使用索引优化 $sort 操作。

总结

MongoDB 的聚合操作通过 聚合管道 实现复杂的数据处理功能,包括筛选、分组、排序、计算等操作。常用阶段如 $match$group$project 等提供了丰富的功能,适用于各种统计和数据转换需求。在实际应用中,通过合理设计聚合管道和索引,可以显著提升查询性能和数据处理效率。

发表评论

后才能评论