分组与总计
本页内容
简介
在本教程中,您将学习如何使用Node.js驱动程序构建聚合管道,对集合进行聚合,并通过完成和运行一个示例应用程序来打印结果。此聚合执行以下操作:
通过字段值匹配文档的子集
按公共字段值对文档进行分组
为每个结果文档添加计算字段
聚合任务摘要
本教程演示了如何对客户订单数据进行分组和分析。结果显示了2020年购买商品的客户列表,并包括每位客户2020年的订单历史。
本示例使用一个集合,orders
,其中包含描述单个产品订单的文档。由于每个订单只能对应一个客户,因此订单文档按customer_id
字段分组,该字段包含客户电子邮件地址。
开始之前
在开始本教程之前,请完成聚合模板应用的设置说明,以配置一个可用的Node.js应用程序。
设置应用后,通过添加以下代码到应用程序中,访问orders
集合
const ordersColl = aggDB.collection("orders");
删除任何现有数据,并按照以下代码示例将示例数据插入到orders
集合中
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);
教程
为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, }, });
为按电子邮件地址分组添加一个分组阶段
为按customer_id
字段的值分组订单添加一个$group阶段。在这个阶段中,添加以下字段到结果文档中的聚合操作
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 阶段,以从 _id
字段中的值重建 customer_id
字段,这些值是在 $group
阶段设置的。
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上的完成的分组和总计应用。