聚合

收藏231

阅读2583

更新时间2025-08-13

聚合管道(Aggregation Pipelines)

聚合操作允许你进行分组、排序、执行计算、分析数据等更多操作。

聚合管道可以有一个或多个“阶段”。这些阶段的顺序很重要。每个阶段都会对前一个阶段的结果进行操作。

实例

db.posts.aggregate([
  // 第一阶段:只查找具有超过 1 个点赞的文档
  {
    $match: { likes: { $gt: 1 } }
  },
  // 第二阶段:按类别对文档进行分组,并对每个类别的点赞数进行求和
  {
    $group: { _id: "$category", totalLikes: { $sum: "$likes" } }
  }
])

运行实例

样本数据

为了演示聚合管道中阶段的使用,我们将把示例数据加载到我们的数据库中。

在 MongoDB Atlas 仪表板中,转到“数据库”。点击省略号并选择“加载示例数据集”。这将把几个示例数据集加载到你的数据库中。

在接下来的部分中,我们将使用此示例数据更详细地探讨几个聚合管道阶段。

聚合 $group

此聚合阶段按提供的唯一 _id 表达式对文档进行分组。

不要将此 _id 表达式与提供给每个文档的 _id ObjectId 混淆。

实例

在此例中,我们使用了从“聚合介绍”部分中的示例数据加载的“sample_airbnb”数据库。

db.listingsAndReviews.aggregate(
    [ { $group : { _id : "$property_type" } } ]
)

运行实例

这将返回 property_type 字段中的不同值。

聚合 $limit

此聚合阶段限制了传递到下一阶段的文档数量。

实例

在此例中,我们使用了从“聚合介绍”部分中的示例数据加载的“sample_mflix”数据库。

db.movies.aggregate([ { $limit: 1 } ])

运行实例

这将从集合中返回 1 部电影。

聚合 $project

此聚合阶段仅将指定字段传递到下一个聚合阶段。

这与 find() 方法使用的投影相同。

实例

在此例中,我们使用了从“聚合介绍”部分中的示例数据加载的“sample_restaurants”数据库。

db.restaurants.aggregate([
  {
    $project: {
      "name": 1,
      "cuisine": 1,
      "address": 1
    }
  },
  {
    $limit: 5
  }
])

运行实例

这将返回文档,但仅包含指定的字段。

请注意,_id 字段也被包含在内。除非明确排除,否则此字段始终包含在内。

我们使用 1 来包含字段,使用 0 来排除字段。

注意:您不能在同一对象中同时使用 0 和 1。唯一的例外是 _id 字段。您应该指定要包含的字段或要排除的字段。

聚合 $sort

此聚合阶段将所有文档按照指定的排序顺序进行分组排序。

请记住,阶段的顺序很重要。每个阶段只对前一阶段提供的文档进行操作。

实例

在这个例子中,我们使用了从聚合介绍”部分的示例数据中加载的“sample_airbnb”数据库。

db.listingsAndReviews.aggregate([ 
  { 
    $sort: { "accommodates": -1 } 
  },
  {
    $project: {
      "name": 1,
      "accommodates": 1
    }
  },
  {
    $limit: 5
  }
])

运行实例

这将返回按 accommodates 字段降序排序的文档。

可以使用 1-1 来选择排序顺序。1 为升序,-1 为降序。

聚合 $match

此聚合阶段的行为类似于查找。它将过滤与所提供的查询匹配的文档。

在管道中尽早使用 $match 可以提高性能,因为它限制了下一阶段必须处理的文档数量。

实例

在此例中,我们使用了从“聚合介绍”部分中的示例数据加载的“sample_airbnb”数据库。

db.listingsAndReviews.aggregate([ 
  { $match : { property_type : "House" } },
  { $limit: 2 },
  { $project: {
    "name": 1,
    "bedrooms": 1,
    "price": 1
  }}
])

运行实例

这将只返回 property_type 为 "House" 的文档。

聚合 $addFields

此聚合阶段向文档添加新字段。

实例

在这个例子中,我们使用了从“聚合介绍”部分的示例数据中加载的“sample_restaurants”数据库。

db.restaurants.aggregate([
  {
    $addFields: {
      avgGrade: { $avg: "$grades.score" }
    }
  },
  {
    $project: {
      "name": 1,
      "avgGrade": 1
    }
  },
  {
    $limit: 5
  }
])

运行实例

这将返回文档以及一个新字段 avgGrade,该字段将包含每家餐馆 grades.score 的平均值。

聚合 $count

此聚合阶段计算从上一阶段传递的文档总数。

实例

在这个例子中,我们使用了从“聚合介绍”部分的示例数据中加载的“sample_restaurants”数据库。

db.restaurants.aggregate([
  {
    $match: { "cuisine": "Chinese" }
  },
  {
    $count: "totalChinese"
  }
])

运行实例

这将返回 $count 阶段中文档的数量,并将其作为名为 "totalChinese" 的字段。

聚合 $lookup

此聚合阶段对同一数据库中的集合执行左外连接。

有四个必填字段:

from 用于在同一数据库中查找的集合。
localField 主要集合中的字段,可用作 from 集合中的唯一标识符。
foreignField from 集合中的字段,可用作主要集合中的唯一标识符。
as 将包含 from 集合中匹配文档的新字段的名称。

实例

在此例中,我们使用了从“聚合介绍”部分中的示例数据加载的“sample_mflix”数据库。

db.comments.aggregate([
  {
    $lookup: {
      from: "movies",
      localField: "movie_id",
      foreignField: "_id",
      as: "movie_details",
    },
  },
  {
    $limit: 1
  }
])

运行实例

这将返回与每条评论相关的电影数据。

聚合 $out

此聚合阶段将从聚合管道返回的文档写入集合。

$out 阶段必须是聚合管道的最后阶段。

实例

在此例中,我们使用了从“聚合介绍”部分的示例数据中加载的“sample_airbnb”数据库。

db.listingsAndReviews.aggregate([
  {
    $group: {
      _id: "$property_type",
      properties: {
        $push: {
          name: "$name",
          accommodates: "$accommodates",
          price: "$price",
        },
      },
    },
  },
  { $out: "properties_by_type" },
])

运行实例

第一阶段将根据 property_type 对属性进行分组,并为每个属性包含 nameaccommodatesprice 字段。$out 阶段将在当前数据库中创建一个名为 properties_by_type 的新集合,并将结果文档写入该集合。

相关

视频

RELATED VIDEOS

更多

免费

MySQLi面向过程极速入门
中级 MySQLi面向过程极速入门

127669次学习

收藏

免费

MySQLi面向对象编程极速入门

免费

MySQL权威开发指南(教程)

免费

MySQL高级进阶视频教程
高级 MySQL高级进阶视频教程

122147次学习

收藏

免费

肖文吉Oracle视频教程
初级 肖文吉Oracle视频教程

72226次学习

收藏

免费

魔乐科技oracle视频教程
初级 魔乐科技oracle视频教程

54966次学习

收藏

科技资讯

更多

精选课程

更多
前端入门_HTML5
前端入门_HTML5

共29课时

61.7万人学习

CSS视频教程-玉女心经版
CSS视频教程-玉女心经版

共25课时

39.3万人学习

JavaScript极速入门_玉女心经系列
JavaScript极速入门_玉女心经系列

共43课时

70.9万人学习

独孤九贱(1)_HTML5视频教程
独孤九贱(1)_HTML5视频教程

共25课时

61.6万人学习

独孤九贱(2)_CSS视频教程
独孤九贱(2)_CSS视频教程

共22课时

23万人学习

独孤九贱(3)_JavaScript视频教程
独孤九贱(3)_JavaScript视频教程

共28课时

33.9万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时

125万人学习

关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号