MongoDB 聚合(Aggregation)
                           
天天向上
发布: 2025-03-07 22:58:21

原创
886 人浏览过

MongoDB 聚合(Aggregation) 通过 aggregate() 方法对文档进行复杂的数据处理,如分组、过滤、排序、计算统计值等,类似 SQL 的 GROUP BYHAVING 语句。


1. 聚合管道(Aggregation Pipeline)

MongoDB 采用 Pipeline(管道)机制,多个操作可以依次处理数据,每个操作的输出作为下一个操作的输入。

db.collection.aggregate([
  { stage1 },
  { stage2 },
  { stage3 }
])
  • 每个 stage(阶段) 是一个数据处理步骤,MongoDB 依次执行。

2. 主要聚合操作符

操作符作用
$match过滤数据(类似 SQL WHERE
$group分组(类似 SQL GROUP BY
$sort排序(类似 SQL ORDER BY
$project指定返回字段(类似 SQL SELECT
$limit限制返回数量(类似 SQL LIMIT
$skip跳过指定数量的文档(类似 SQL OFFSET
$count统计总数
$unwind拆分数组
$lookup关联查询(类似 SQL JOIN
$addFields添加计算字段
$set修改或新增字段(MongoDB 4.2+)
$unset移除字段
$merge结果存入新集合

3. 过滤数据($match)

$match 作用类似 WHERE,用于筛选符合条件的数据,减少后续处理的数据量。

示例

查询 status"active"price > 100 的商品:

db.products.aggregate([
  { $match: { status: "active", price: { $gt: 100 } } }
])

等价于 SQL:

SELECT * FROM products WHERE status = 'active' AND price > 100;

4. 分组统计($group)

$group 类似 SQL GROUP BY,可以按照某字段分组,并计算统计值

示例

category 分组,统计每个类别的商品数量:

db.products.aggregate([
  { $group: { _id: "$category", count: { $sum: 1 } } }
])
  • _id: "$category" → 按 category 分组。
  • count: { $sum: 1 } → 统计该分组内的文档数。

等价于 SQL:

SELECT category, COUNT(*) FROM products GROUP BY category;

其他常用统计运算

操作符作用
$sum计算总和
$avg计算平均值
$max计算最大值
$min计算最小值
$first取分组中的第一个值
$last取分组中的最后一个值

5. 指定返回字段($project)

$project 用于指定需要返回的字段,类似 SQL SELECT

示例

仅返回 nameprice 字段:

db.products.aggregate([
  { $project: { name: 1, price: 1, _id: 0 } }
])
  • 1 表示显示该字段。
  • _id: 0 表示隐藏 _id 字段(MongoDB 默认会返回 _id)。

等价于 SQL:

SELECT name, price FROM products;

计算新字段

使用 $project 计算新字段:

db.products.aggregate([
  { $project: { name: 1, priceWithTax: { $multiply: ["$price", 1.1] } } }
])
  • priceWithTax 是计算后的新字段(商品价格 × 1.1)。

6. 排序($sort)

$sort 类似 SQL ORDER BY,用于对结果排序

示例

price 降序排序:

db.products.aggregate([
  { $sort: { price: -1 } }
])
  • 1 表示升序(ASC)。
  • -1 表示降序(DESC)。

等价于 SQL:

SELECT * FROM products ORDER BY price DESC;

7. 限制 & 跳过($limit & $skip)

  • $limit限制返回数量
  • $skip跳过指定数量的文档(通常用于分页)。

示例

获取第 2 页,每页 5 条数据

db.products.aggregate([
  { $skip: 5 },  // 跳过前 5 条
  { $limit: 5 }  // 获取 5 条
])

等价于 SQL:

SELECT * FROM products LIMIT 5 OFFSET 5;

8. 拆分数组($unwind)

$unwind 将数组字段拆分成多行数据

示例

假设 orders 集合的 items 字段是数组:

{ _id: 1, customer: "Alice", items: ["Apple", "Banana"] }
{ _id: 2, customer: "Bob", items: ["Orange"] }

使用 $unwind 拆分:

db.orders.aggregate([
  { $unwind: "$items" }
])

结果:

{ _id: 1, customer: "Alice", items: "Apple" }
{ _id: 1, customer: "Alice", items: "Banana" }
{ _id: 2, customer: "Bob", items: "Orange" }

等价于 SQL 一对多拆分


9. 关联查询($lookup,类似 SQL JOIN)

MongoDB 没有外键,但可以使用 $lookup 进行类似 SQL JOIN 的查询。

示例

orders 集合中查询 users 表的用户信息:

db.orders.aggregate([
  {
    $lookup: {
      from: "users",       // 关联集合
      localField: "userId", // 当前集合的字段
      foreignField: "_id",  // 目标集合的字段
      as: "userInfo"       // 关联数据的字段名
    }
  }
])

等价于 SQL:

SELECT orders.*, users.*
FROM orders
JOIN users ON orders.userId = users._id;

10. 统计文档数($count)

统计 status="active" 的商品数:

db.products.aggregate([
  { $match: { status: "active" } },
  { $count: "totalActiveProducts" }
])

总结

操作MongoDB 聚合SQL 对应
过滤$matchWHERE
分组$groupGROUP BY
计算$sum, $avg, $maxSUM(), AVG(), MAX()
排序$sortORDER BY
限制返回$limitLIMIT
跳过$skipOFFSET
选择字段$projectSELECT
拆分数组$unwind无直接对应
关联查询$lookupJOIN

MongoDB 聚合 是强大的数据处理工具,可以实现复杂的数据分析!更多详细内容请关注其他相关文章!

发表回复 0

Your email address will not be published. Required fields are marked *