Docs 菜单
Docs 主页
/
MongoDB Shell

运行聚合管道

在此页面上

  • 了解聚合事务语法
  • 例子

您可以使用 MongoDB Shell 在集合上运行聚合管道。聚合管道根据选定的管道阶段将文档转换为汇总结果。

聚合的常见用途包括:

  • 按给定表达式对数据进行分组。

  • 基于多个字段计算结果,并将这些结果存储在新字段中。

  • 筛选数据以返回与给定条件匹配的子集。

  • 对数据进行排序。

运行聚合时,MongoDB Shell 会将结果直接输出到终端。

MongoDB 聚合管道由多个阶段组成。每个阶段都会在文档通过管道时对其进行转换。管道阶段不需要为每个输入文档都生成一个输出文档;例如,某些阶段可能会生成新文档或过滤文档。

要创建聚合管道,请在 MongoDB Shell 中使用以下语法:

1db.<collection>.aggregate([
2 {
3 <$stage1>
4 },
5 {
6 <$stage2>
7 }
8 ...
9])

本页的示例参考了 Atlas 示例数据集。您可以创建一个免费的 Atlas 集群,并用示例数据填充该集群,以遵循这些示例。要了解更多信息,请参阅开始使用 Atlas

以下示例使用了 Atlas sample_mflix 示例数据集中的 movies 集合。

movies集合中的每个文档都描述一部电影:

1{
2 _id: 573a1397f29313caabce8347,
3 fullplot: 'In a cyberpunk vision of the future, man has developed the technology to create replicants, human clones used to serve in the colonies outside Earth but with fixed lifespans. In Los Angeles, 2019, Deckard is a Blade Runner, a cop who specializes in terminating replicants. Originally in retirement, he is forced to re-enter the force when four replicants escape from an off-world colony to Earth.',
4 imdb: { rating: 8.2, votes: 419589, id: 83658 },
5 year: 1982,
6 plot: 'A blade runner must pursue and try to terminate four replicants who stole a ship in space and have returned to Earth to find their creator.',
7 genres: [ 'Sci-Fi', 'Thriller' ],
8 rated: 'R',
9 metacritic: 88,
10 title: 'Blade Runner',
11 lastupdated: '2015-09-04 00:05:51.990000000',
12 languages: [ 'English', 'German', 'Cantonese', 'Japanese', 'Hungarian' ],
13 writers: [
14 'Hampton Fancher (screenplay)',
15 'David Webb Peoples (screenplay)',
16 'Philip K. Dick (novel)'
17 ],
18 type: 'movie',
19 tomatoes: {
20 viewer: { rating: 4, numReviews: 331213, meter: 91 },
21 dvd: 1997-08-27T00:00:00.000Z,
22 critic: { rating: 8.5, numReviews: 102, meter: 90 },
23 lastUpdated: 2015-09-12T17:48:21.000Z,
24 consensus: "Misunderstood when it first hit theaters, the influence of Ridley Scott's mysterious, neo-noir Blade Runner has deepened with time. A visually remarkable, achingly human sci-fi masterpiece.",
25 rotten: 10,
26 production: 'Warner Bros. Pictures',
27 fresh: 92
28 },
29 poster: 'https://m.media-amazon.com/images/M/MV5BNzQzMzJhZTEtOWM4NS00MTdhLTg0YjgtMjM4MDRkZjUwZDBlXkEyXkFqcGdeQXVyNjU0OTQ0OTY@._V1_SY1000_SX677_AL_.jpg',
30 num_mflix_comments: 1,
31 released: 1982-06-25T00:00:00.000Z,
32 awards: {
33 wins: 13,
34 nominations: 15,
35 text: 'Nominated for 2 Oscars. Another 11 wins & 15 nominations.'
36 },
37 countries: [ 'USA', 'Hong Kong', 'UK' ],
38 cast: [
39 'Harrison Ford',
40 'Rutger Hauer',
41 'Sean Young',
42 'Edward James Olmos'
43 ],
44 directors: [ 'Ridley Scott' ],
45 runtime: 117
46}

本教程中聚合的文档位于sample_mflix.movies集合中。使用以下命令切换到包含此集合的数据库:

use sample_mflix

以以下管道为例:

1db.movies.aggregate([
2
3 // First Stage
4
5 { $project: { _id: 0, genres: 1, imdb: 1, title: 1 } },
6
7 // Second Stage
8
9 { $unwind: "$genres" },
10
11 // Third Stage
12
13 { $group:
14 { _id: "$genres",
15 averageGenreRating: { $avg: "$imdb.rating" }
16 }
17 },
18
19 // Fourth Stage
20
21 { $sort: { averageGenreRating: -1 } }
22] )

该管道分四个阶段执行聚合:

第一个阶段:

$project 阶段将包含以下字段的文档传递给下一个管道阶段:

  • genres

  • imdb

  • title

不包含这些字段的文档不会被传递到下一个管道阶段。

注意

$project 阶段会指定 _id: 0 以抑制其传递到下一个阶段的文档中的 _id 字段。

有关更多信息,请参阅 MongoDB 手册。

$project 阶段转换示例文档并将以下输出传递给下一个管道阶段:

1{
2 imdb: { rating: 8.2, votes: 419589, id: 83658 },
3 genres: [ 'Sci-Fi', 'Thriller' ],
4 title: 'Blade Runner'
5}
第二阶段

$unwind 阶段将 genres 数组中每个元素的文档传递给下一个管道阶段。

$unwind 阶段从原始示例文档生成以下两个文档,然后将其传递给下一管道阶段:

1{
2 imdb: { rating: 8.2, votes: 419589, id: 83658 },
3 genres: 'Sci-Fi',
4 title: 'Blade Runner'
5}
1{
2 imdb: { rating: 8.2, votes: 419589, id: 83658 },
3 genres: 'Thriller',
4 title: 'Blade Runner'
5}
第三个阶段

$group 阶段:

  • 从上一个管道阶段收到的文档中检索不同的类型值,

  • 为每个不同的类型创建文档,其中 _id 是类型名称,

  • 向每个新文档添加一个字段averageGenreRating,其中包含与该类型匹配的所有文档的平均值imdb.rating,并且

  • 将新文档传递到下一个管道阶段。

此阶段将类似于以下内容的文档发送到下一个管道阶段:

1{ _id: 'Sport', averageGenreRating: 6.781233933161954 },
2{ _id: 'History', averageGenreRating: 7.202306920762287 },
3{ _id: 'Biography', averageGenreRating: 7.097142857142857 },
4{ _id: 'Adventure', averageGenreRating: 6.527788649706458 },
5{ _id: 'Family', averageGenreRating: 6.36096256684492 },
6{ _id: 'Crime', averageGenreRating: 6.730478683620045 },
7{ _id: 'Western', averageGenreRating: 6.879197080291971 },
8{ _id: 'Fantasy', averageGenreRating: 6.42495652173913 },
9{ _id: 'Talk-Show', averageGenreRating: 7 },
10{ _id: 'Documentary', averageGenreRating: 7.365266635205286 },
11{ _id: 'War', averageGenreRating: 7.183944374209861 },
12{ _id: 'Short', averageGenreRating: 7.355813953488372 },
13{ _id: 'Horror', averageGenreRating: 5.84110718492344 },
14{ _id: 'Film-Noir', averageGenreRating: 7.503809523809523 },
15{ _id: 'News', averageGenreRating: 7.254901960784314 },
16{ _id: 'Thriller', averageGenreRating: 6.322121555303888 },
17{ _id: 'Action', averageGenreRating: 6.3774842271293375 },
18{ _id: 'Music', averageGenreRating: 6.923452380952381 },
19{ _id: 'Animation', averageGenreRating: 6.917993795243019 },
20{ _id: 'Drama', averageGenreRating: 6.830528688822631 }
第四阶段
$sort 阶段根据 averageGenreRating 字段的值对从上一阶段接收的文档进行降序排序。

运行示例管道时,MongoDB Shell 会在终端打印类似以下内容的文档:

1[
2 { _id: 'Film-Noir', averageGenreRating: 7.503809523809523 },
3 { _id: 'Documentary', averageGenreRating: 7.365266635205286 },
4 { _id: 'Short', averageGenreRating: 7.355813953488372 },
5 { _id: 'News', averageGenreRating: 7.254901960784314 },
6 { _id: 'History', averageGenreRating: 7.202306920762287 },
7 { _id: 'War', averageGenreRating: 7.183944374209861 },
8 { _id: 'Biography', averageGenreRating: 7.097142857142857 },
9 { _id: 'Talk-Show', averageGenreRating: 7 },
10 { _id: 'Music', averageGenreRating: 6.923452380952381 },
11 { _id: 'Animation', averageGenreRating: 6.917993795243019 },
12 { _id: 'Western', averageGenreRating: 6.879197080291971 },
13 { _id: 'Drama', averageGenreRating: 6.830528688822631 },
14 { _id: 'Sport', averageGenreRating: 6.781233933161954 },
15 { _id: 'Crime', averageGenreRating: 6.730478683620045 },
16 { _id: 'Musical', averageGenreRating: 6.696913580246913 },
17 { _id: 'Romance', averageGenreRating: 6.695711554220159 },
18 { _id: 'Mystery', averageGenreRating: 6.563317384370015 },
19 { _id: 'Adventure', averageGenreRating: 6.527788649706458 },
20 { _id: 'Comedy', averageGenreRating: 6.479626461362988 },
21 { _id: 'Fantasy', averageGenreRating: 6.42495652173913 }
22]

提示

另请参阅:

后退

删除