文档菜单
文档首页
/ / /
Node.js 驱动程序
/

分组与总计

本页内容

  • 简介
  • 聚合任务摘要
  • 开始之前
  • 教程
  • 为 2020 年的订单添加一个匹配阶段
  • 添加一个按订单日期排序的阶段
  • 添加一个按电子邮件地址分组的阶段
  • 添加一个按首次订单日期排序的阶段
  • 添加一个设置阶段以显示电子邮件地址
  • 添加一个未设置阶段以删除不必要的字段
  • 运行聚合管道
  • 解读结果

在本教程中,您将学习如何使用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);
1

首先,添加一个$match阶段,匹配2020年下订单的订单

pipeline.push({
$match: {
orderdate: {
$gte: new Date("2020-01-01T00:00:00Z"),
$lt: new Date("2021-01-01T00:00:00Z"),
},
},
});
2

接下来,添加一个$sort阶段,对orderdate字段进行升序排序,以便在下一阶段展示每个客户的最早2020年购买订单

pipeline.push({
$sort: {
orderdate: 1,
},
});
3

为按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"
}
},
},
});
4

接下来,添加另一个$sort阶段,按升序对first_purchase_date字段进行排序

pipeline.push({
$sort: {
first_purchase_date: 1,
},
});
5

在聚合管道中添加一个 $set 阶段,以从 _id 字段中的值重建 customer_id 字段,这些值是在 $group 阶段设置的。

pipeline.push({
$set: {
customer_id: "$_id",
},
});
6

最后,添加一个 $unset 阶段。该 $unset 阶段将从结果文档中删除 _id 字段。

pipeline.push({ $unset: ["_id"] });
7

将以下代码添加到您的应用程序末尾以在 orders 集合上执行聚合。

const aggregationResult = await ordersColl.aggregate(pipeline);

最后,在您的 shell 中运行以下命令以启动应用程序。

node agg_tutorial.js
8

聚合返回以下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上的完成的分组和总计应用

返回

过滤子集