Docs 菜单
Docs 主页
/ / /
pymongo
/ /

群组和总计

在此页面上

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

在本教程中,您可以学习如何使用 PyMongo 构建聚合管道,对集合执行聚合,并通过完成和运行示例应用来打印结果。 此聚合执行以下操作:

  • 根据字段值匹配文档子集

  • 按公共字段值对文档进行分组

  • 将计算字段添加到每个结果文档

本教程演示如何对客户订单数据进行分组和分析。 结果显示在 2020 年购买过商品的客户列表,并包括每个客户 2020 年的订单历史记录。

此示例使用一个collection orders ,其中包含描述单个产品订单的文档。由于每个订单只能对应一个客户,因此订单文档按customer_id字段分组,其中包含客户电子邮件地址。

在开始本教程之前,请完成聚合模板应用说明,以设置有效的 Python 应用程序。

设置应用后,通过将以下代码添加到应用程序中来访问 orders 集合:

orders_coll = agg_db["orders"]

删除所有现有数据,并将样本数据插入orders collection,如以下代码所示:

orders_coll.delete_many({})
order_data = [
{
"customer_id": "elise_smith@myemail.com",
"orderdate": datetime(2020, 5, 30, 8, 35, 52),
"value": 231
},
{
"customer_id": "elise_smith@myemail.com",
"orderdate": datetime(2020, 1, 13, 9, 32, 7),
"value": 99
},
{
"customer_id": "oranieri@warmmail.com",
"orderdate": datetime(2020, 1, 1, 8, 25, 37),
"value": 63
},
{
"customer_id": "tj@wheresmyemail.com",
"orderdate": datetime(2019, 5, 28, 19, 13, 32),
"value": 2
},
{
"customer_id": "tj@wheresmyemail.com",
"orderdate": datetime(2020, 11, 23, 22, 56, 53),
"value": 187
},
{
"customer_id": "tj@wheresmyemail.com",
"orderdate": datetime(2020, 8, 18, 23, 4, 48),
"value": 4
},
{
"customer_id": "elise_smith@myemail.com",
"orderdate": datetime(2020, 12, 26, 8, 55, 46),
"value": 4
},
{
"customer_id": "tj@wheresmyemail.com",
"orderdate": datetime(2021, 2, 28, 7, 49, 32),
"value": 1024
},
{
"customer_id": "elise_smith@myemail.com",
"orderdate": datetime(2020, 10, 3, 13, 49, 44),
"value": 102
}
]
orders_coll.insert_many(order_data)
1

首先,添加一个 $match阶段,用于匹配2020中的订单:

pipeline.append({
"$match": {
"orderdate": {
"$gte": datetime(2020, 1, 1, 0, 0, 0),
"$lt": datetime(2021, 1, 1, 0, 0, 0)
}
}
})
2

接下来,添加一个$sort阶段以对orderdate字段设置升序排序,从而在下一阶段显示每个客户最早的2020购买:

pipeline.append({
"$sort": {
"orderdate": 1
}
})
3

添加$group阶段以按customer_id字段的值对订单进行分组。 在此阶段,添加聚合操作,在结果文档中创建以下字段:

  • first_purchase_date:客户首次购买的日期

  • total_value:客户所有购买的总价值

  • total_orders:客户的购买总数

  • orders:客户的所有购买清单,包括每次购买的日期和价值

pipeline.append({
"$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.append({
"$sort": {
"first_purchase_date": 1
}
})
5

添加$set阶段,以根据$group阶段设置的_id字段中的值重新创建customer_id字段:

pipeline.append({
"$set": {
"customer_id": "$_id"
}
})
6

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

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

将以下代码添加到应用程序末尾,以对orderscollection执行聚合:

aggregation_result = orders_coll.aggregate(pipeline)

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

python3 agg_tutorial.py
8

该聚合返回 2020 年以来客户订单的以下摘要:

{
'first_purchase_date': datetime.datetime(2020, 1, 1, 8, 25, 37),
'total_value': 63,
'total_orders': 1,
'orders': [ { 'orderdate': datetime.datetime(2020, 1, 1, 8, 25, 37), 'value': 63 } ],
'customer_id': 'oranieri@warmmail.com'
}
{
'first_purchase_date': datetime.datetime(2020, 1, 13, 9, 32, 7),
'total_value': 436,
'total_orders': 4,
'orders': [
{ 'orderdate': datetime.datetime(2020, 1, 13, 9, 32, 7), 'value': 99 },
{ 'orderdate': datetime.datetime(2020, 5, 30, 8, 35, 52), 'value': 231 },
{ 'orderdate': datetime.datetime(2020, 10, 3, 13, 49, 44), 'value': 102 },
{ 'orderdate': datetime.datetime(2020, 12, 26, 8, 55, 46), 'value': 4 }
],
'customer_id': 'elise_smith@myemail.com'
}
{
'first_purchase_date': datetime.datetime(2020, 8, 18, 23, 4, 48),
'total_value': 191,
'total_orders': 2,
'orders': [
{ 'orderdate': datetime.datetime(2020, 8, 18, 23, 4, 48), 'value': 4 },
{ 'orderdate': datetime.datetime(2020, 11, 23, 22, 56, 53), 'value': 187 }
],
'customer_id': 'tj@wheresmyemail.com'
}

结果文档包含来自给定客户的所有订单的详细信息,按客户的电子邮件地址分组。

要查看本教程的完整代码,请参阅 Completed Group 和 Total App 在Github 上。

后退

过滤的子集

来年

解压数组并进行分组