群组和总计
在此页面上
简介
在本教程中,您可以学习如何使用 Node.js 驱动程序构建聚合管道、对集合执行聚合,以及通过完成和运行示例应用程序来打印结果。此聚合执行以下操作:
根据字段值匹配文档子集
按公共字段值对文档进行分组
将计算字段添加到每个结果文档
聚合任务摘要
本教程演示如何对客户订单数据进行分组和分析。 结果显示在 2020 年购买过商品的客户列表,并包括每个客户 2020 年的订单历史记录。
此示例使用一个collection orders
,其中包含描述单个产品订单的文档。由于每个订单只能对应一个客户,因此订单文档按customer_id
字段分组,其中包含客户电子邮件地址。
开始之前
在开始本教程之前,请完成聚合模板应用说明,以设立有效的 Node.js应用程序。
设置应用后,通过将以下代码添加到应用程序中来访问 orders
集合:
const ordersColl = aggDB.collection("orders");
删除所有现有数据,并将样本数据插入orders
collection,如以下代码所示:
await ordersColl.deleteMany({}); const orderData = [ { customer_id: "elise_smith@myemail.com", orderdate: new Date("2020-05-30T08:35:52Z"), value: 231, }, { customer_id: "elise_smith@myemail.com", orderdate: new Date("2020-01-13T09:32:07Z"), value: 99, }, { customer_id: "oranieri@warmmail.com", orderdate: new Date("2020-01-01T08:25:37Z"), value: 63, }, { customer_id: "tj@wheresmyemail.com", orderdate: new Date("2019-05-28T19:13:32Z"), value: 2, }, { customer_id: "tj@wheresmyemail.com", orderdate: new Date("2020-11-23T22:56:53Z"), value: 187, }, { customer_id: "tj@wheresmyemail.com", orderdate: new Date("2020-08-18T23:04:48Z"), value: 4, }, { customer_id: "elise_smith@myemail.com", orderdate: new Date("2020-12-26T08:55:46Z"), value: 4, }, { customer_id: "tj@wheresmyemail.com", orderdate: new Date("2021-02-29T07:49:32Z"), value: 1024, }, { customer_id: "elise_smith@myemail.com", orderdate: new Date("2020-10-03T13:49:44Z"), value: 102, }, ]; await ordersColl.insertMany(orderData);
Tutorial
为 2020 年订单添加匹配阶段
首先,添加一个 $match阶段,用于匹配2020中的订单:
pipeline.push({ $match: { orderdate: { $gte: new Date("2020-01-01T00:00:00Z"), $lt: new Date("2021-01-01T00:00:00Z"), }, }, });
添加排序阶段以按订单日期排序
接下来,添加一个$sort阶段以对orderdate
字段设置升序排序,从而在下一阶段显示每个客户最早的2020购买:
pipeline.push({ $sort: { orderdate: 1, }, });
将小组赛阶段添加到按电子邮件地址分组
添加$group阶段以按customer_id
字段的值对订单进行分组。 在此阶段,添加聚合操作,在结果文档中创建以下字段:
first_purchase_date
:客户首次购买的日期total_value
:客户所有购买的总价值total_orders
:客户的购买总数orders
:客户的所有购买清单,包括每次购买的日期和价值
pipeline.push({ $group: { _id: "$customer_id", first_purchase_date: { $first: "$orderdate" }, total_value: { $sum: "$value" }, total_orders: { $sum: 1 }, orders: { $push: { orderdate: "$orderdate", value: "$value" } }, }, });
添加排序阶段以按首个订单日期排序
接下来,添加另一个$sort阶段,对first_purchase_date
字段设置升序排序:
pipeline.push({ $sort: { first_purchase_date: 1, }, });
添加设置阶段以显示电子邮件地址
添加$set阶段,以根据$group
阶段设置的_id
字段中的值重新创建customer_id
字段:
pipeline.push({ $set: { customer_id: "$_id", }, });
添加未设置阶段以删除不需要的字段
最后,添加一个$unset阶段。 $unset
阶段从结果文档中删除_id
字段:
pipeline.push({ $unset: ["_id"] });
解释结果
该聚合返回 2020 年以来客户订单的以下摘要:
{ first_purchase_date: 2020-01-01T08:25:37.000Z, total_value: 63, total_orders: 1, orders: [ { orderdate: 2020-01-01T08:25:37.000Z, value: 63 } ], customer_id: 'oranieri@warmmail.com' } { first_purchase_date: 2020-01-13T09:32:07.000Z, total_value: 436, total_orders: 4, orders: [ { orderdate: 2020-01-13T09:32:07.000Z, value: 99 }, { orderdate: 2020-05-30T08:35:52.000Z, value: 231 }, { orderdate: 2020-10-03T13:49:44.000Z, value: 102 }, { orderdate: 2020-12-26T08:55:46.000Z, value: 4 } ], customer_id: 'elise_smith@myemail.com' } { first_purchase_date: 2020-08-18T23:04:48.000Z, total_value: 191, total_orders: 2, orders: [ { orderdate: 2020-08-18T23:04:48.000Z, value: 4 }, { orderdate: 2020-11-23T22:56:53.000Z, value: 187 } ], customer_id: 'tj@wheresmyemail.com' }
结果文档包含来自给定客户的所有订单的详细信息,按客户的电子邮件地址分组。
要查看本教程的完整代码,请参阅Github上的 Completed Group and Total App Github。