聚合(Aggregation)
Overview
在本指南中,您可了解如何在 MongoDB Node.js 驱动程序中使用聚合操作。
聚合操作是一种表达式,可用于在 MongoDB 中生成归约和汇总的结果。MongoDB 的聚合框架允许您创建一个由一个或多个阶段组成的管道,每个阶段可对您的数据执行特定的操作。
类比
您可将聚合管道近似理解为汽车工厂。工厂需将各种装配站组织成装配线,才能进行汽车制造。每个装配站均有专门的工具,例如钻头和焊机。工厂会改造初始零件和材料并组装为成品。
聚合管道是装配线,聚合阶段是装配站,表达式操作符是专用的工具。
比较聚合与查询操作
使用查询操作(例如 find()
方法),您可以执行以下操作:
选择要返回的文档
选择要返回哪些字段
对结果进行排序
通过使用聚合操作,可执行以下操作:
执行所有查询操作
重命名字段
计算字段
汇总数据
对值进行分组
聚合操作存在一些 限制:
返回的文档不得违反 16 兆字节的 BSON 文档大小限制。
默认情况下,管道阶段的内存限制为 100 MB。您可以通过将
AggregateOptions
的allowDiskUse
属性设置为true
来超过此限制。请参阅 AggregateOptions API 文档,了解更多详情。
参考
要查看表达式操作符的完整列表,请参阅服务器手册中的聚合操作符。
要了解如何组装聚合管道和查看示例,请参阅服务器手册中的聚合管道。
要了解有关创建管道阶段的更多信息,请参阅服务器手册中的聚合阶段。
可运行示例
该示例使用有关餐馆的样本数据。以下代码将数据插入到 aggregation
数据库的 restaurants
集合中:
const db = client.db("aggregation"); const coll = db.collection("restaurants"); // Create sample documents const docs = [ { stars: 3, categories: ["Bakery", "Sandwiches"], name: "Rising Sun Bakery" }, { stars: 4, categories: ["Bakery", "Cafe", "Bar"], name: "Cafe au Late" }, { stars: 5, categories: ["Coffee", "Bakery"], name: "Liz's Coffee Bar" }, { stars: 3, categories: ["Steak", "Seafood"], name: "Oak Steakhouse" }, { stars: 4, categories: ["Bakery", "Dessert"], name: "Petit Cookie" }, ]; // Insert documents into the restaurants collection const result = await coll.insertMany(docs);
提示
有关连接 MongoDB 部署的更多信息,请参阅 连接指南。
聚合示例
如需执行聚合,请向 collection.aggregate()
方法传递聚合阶段列表。
在示例中,aggregation pipeline 使用以下聚合阶段:
$match 阶段来过滤其
categories
数组字段包含Bakery
元素的文档。一个 $group 阶段,它可按
stars
字段对匹配的文档进行分组,从而为stars
的每个不同值累积文档数。
// Define an aggregation pipeline with a match stage and a group stage const pipeline = [ { $match: { categories: "Bakery" } }, { $group: { _id: "$stars", count: { $sum: 1 } } } ]; // Execute the aggregation const aggCursor = coll.aggregate(pipeline); // Print the aggregated results for await (const doc of aggCursor) { console.log(doc); }
此示例生成以下输出:
{ _id: 4, count: 2 } { _id: 3, count: 1 } { _id: 5, count: 1 }
有关更多信息,请参阅aggregate() API 文档。
聚合教程
聚合教程以分步格式提供了常见聚合任务的详细说明。本教程改编自 Paul Done 所著《实用 MongoDB 聚合》(Practical MongoDB Aggregations)一书中的示例。
每个教程都包括以下部分:
简介,描述聚合类型的用途和常见用例。本节还描述了本教程演示的示例和预期结果。
开始之前,这个部分介绍了在构建聚合管道和执行聚合之前必须具备的必要数据库、集合和示例数据。
教程,其中介绍了如何构建和运行聚合管道。本节介绍已完成聚合教程的每个阶段,然后说明如何运行和解释聚合的输出结果。
在每个聚合教程的末尾,您可以找到一个链接,该链接指向在环境中完全可运行的 Node.js 代码文件。
提示
要学习;了解有关执行聚合的更多信息,请参阅聚合指南。
聚合模板应用程序
在开始按照聚合教程进行操作之前,您必须设置一个新的 Node.js 应用。您可以使用此应用连接到 MongoDB 部署、将示例数据插入到 MongoDB 以及运行每个教程中的聚合管道。
提示
要了解如何安装驱动程序和连接 MongoDB,请参阅快速入门指南中的下载和安装以及创建 MongoDB 部署步骤。
安装驱动程序后,创建一个名为agg_tutorial.js
的文件。 将以下代码粘贴到此文件中,为聚合教程创建应用模板:
const { MongoClient } = require("mongodb"); // Replace the placeholder with your connection string. const uri = "<connection string>"; const client = new MongoClient(uri); async function run() { try { const aggDB = client.db("agg_tutorials_db"); // Get a reference to relevant collections. // ... const someColl = // ... const anotherColl = // Delete any existing documents in collections. // ... await someColl.deleteMany({}); // Insert sample data into the collection or collections. // ... const someData = [ ... ]; // ... await someColl.insertMany(someData); // Create an empty pipeline array. const pipeline = []; // Add code to create pipeline stages. // ... pipeline.push({ ... }) // Run the aggregation. // ... const aggregationResult = ... // Print the aggregation results. for await (const document of aggregationResult) { console.log(document); } } finally { await client.close(); } } run().catch(console.dir);
重要
在前面的代码中,请阅读代码注释,找到您必须根据教程进行修改的代码部分。
如果您尝试在不进行任何更改的情况下运行代码,则会遇到连接错误。
对于每个教程,您必须用部署的连接字符串替换连接字符串占位符。
提示
如要了解如何找到部署的连接字符串,请参阅《快速入门》指南中的创建连接字符串步骤。
例如,如果连接字符串为 "mongodb+srv://mongodb-example:27017"
,则其赋值应如下所示:
const uri = "mongodb+srv://mongodb-example:27017";
要在修改教程模板后运行完成的文件,请在 shell 中运行以下命令:
node agg_tutorial.js
可用教程
其他示例
要查看常见聚合任务的分步说明,请参阅聚合教程。
您可在 MongoDB 网站上的 Aggregation Framework with Node.js Tutorial 博客文章中找到另一聚合管道示例。