MongoDB统计客户票据数组元素总数并排序的实现问题
正确实现MongoDB客户票据数字统计的聚合查询
集合数据
customers集合
[ { "_id": 1, "NAME": "CUSTOMER A" }, { "_id": 2, "NAME": "CUSTOMER B" } ]
tickets集合
[ { "_id": 1, "CUSTOMER": 2, "NUMBERS": [1,2,3] }, { "_id": 2, "CUSTOMER": 2, "NUMBERS": [4] }, { "_id": 3, "CUSTOMER": 1, "NUMBERS": [25] } ]
需求说明
统计每位客户在票据中拥有的数字总数,并按总数从高到低排序,期望结果格式如下:
[ { "_id": 2, "NAME": "CUSTOMER B", "COUNTNUMBERS": 4 }, { "_id": 1, "NAME": "CUSTOMER A", "COUNTNUMBERS": 1 } ]
现有问题代码
以下是一段未满足需求的聚合查询代码:
db.tickets.aggregate([ { $unwind: "$CUSTOMER" }, { $group: { _id: "$CUSTOMER", NUMBERS: { $sum: 1 } } }, { $lookup: { let: { "customerId": "$_id"}, from: "customers", pipeline: [ { $match: { $expr: { $eq: ["$_id", "$$customerId"] } } } ], as: "CUSTOMER" } } ])
正确聚合查询方案
现有代码的问题在于:错误展开了$CUSTOMER字段(它是单个值而非数组),分组时统计的是票据数量而非数字总数,且未处理关联后的数组结构、未排序和调整字段格式。
正确的聚合查询步骤如下:
- 展开
tickets集合中的NUMBERS数组,让每个数字单独成为一条文档 - 按客户ID分组,统计每个客户的数字总数
- 关联
customers集合,获取客户名称 - 展开关联得到的客户数组(每个ID对应唯一客户)
- 调整字段结构,重命名为需求中的字段名
- 按数字总数降序排序
完整代码:
db.tickets.aggregate([ // 展开数字数组,每个数字生成一条文档 { $unwind: "$NUMBERS" }, // 按客户ID分组,统计数字总数 { $group: { _id: "$CUSTOMER", COUNTNUMBERS: { $sum: 1 } } }, // 关联customers集合获取客户信息 { $lookup: { from: "customers", localField: "_id", foreignField: "_id", as: "customerInfo" } }, // 展开客户信息数组(每个ID对应一个客户) { $unwind: "$customerInfo" }, // 调整字段结构,匹配期望格式 { $project: { _id: 1, NAME: "$customerInfo.NAME", COUNTNUMBERS: 1 } }, // 按数字总数降序排序 { $sort: { COUNTNUMBERS: -1 } } ])
代码说明
$unwind: "$NUMBERS":将每个票据的数字数组拆分成单独文档,确保每个数字都被计数$group:以客户ID为分组键,用$sum:1统计该客户的数字总个数$lookup:通过客户ID关联customers集合,获取对应的客户名称$unwind: "$customerInfo":将关联得到的数组转为单个对象,方便后续字段提取$project:重新组织字段,将客户名称从关联对象中取出,并保留需要的字段$sort:按COUNTNUMBERS字段降序排列,满足结果排序要求
内容的提问来源于stack exchange,提问作者Winnícius de Moura Alves
相关产品推荐
相关产品推荐

