如何用单条MongoDB聚合查询获取近12/24小时Top客户
单条MongoDB聚合查询实现近12/24小时Top客户统计
核心思路拆解
要在单条聚合中同时输出两个时间段的Top客户,核心是一次过滤数据+分组时分别计算两个时间段的总和+最后聚合排序截取,具体步骤如下:
过滤近24小时数据
先筛选出近24小时的所有记录(近12小时数据是其子集),避免重复处理无关数据:{ $match: { timestamp: { $gte: new Date(Date.now() - 24 * 60 * 60 * 1000) } } }按客户分组,双时间段求和
按客户name和city分组(假设同一客户的城市信息固定),用$cond判断每条记录是否属于近12小时,分别累加得到两个时间段的订单总数:{ $group: { _id: { name: "$name", city: "$city" }, last12Count: { $sum: { $cond: [ { $gte: ["$timestamp", new Date(Date.now() - 12 * 60 * 60 * 1000)] }, "$count", 0 ] } }, last24Count: { $sum: "$count" } } }整理客户数据结构
把分组后的_id字段展开,将客户信息整理成统一格式:{ $project: { _id: 0, name: "$_id.name", city: "$_id.city", last12Count: 1, last24Count: 1 } }聚合生成Top客户列表
将所有客户数据收集到数组中,分别对两个时间段的数组按订单数降序排序,再截取TopN(示例为Top5):{ $group: { _id: null, last12Hours: { $push: { name: "$name", city: "$city", count: "$last12Count" } }, last24Hours: { $push: { name: "$name", city: "$city", count: "$last24Count" } } } }, { $project: { _id: 0, last12Hours: { $slice: [ { $sortArray: { input: "$last12Hours", sortBy: { count: -1 } } }, 5 ] }, last24Hours: { $slice: [ { $sortArray: { input: "$last24Hours", sortBy: { count: -1 } } }, 5 ] } } }
完整聚合查询代码
db.collection.aggregate([ // 步骤1:过滤近24小时数据 { $match: { timestamp: { $gte: new Date(Date.now() - 24 * 60 * 60 * 1000) } } }, // 步骤2:分组计算双时间段总和 { $group: { _id: { name: "$name", city: "$city" }, last12Count: { $sum: { $cond: [ { $gte: ["$timestamp", new Date(Date.now() - 12 * 60 * 60 * 1000)] }, "$count", 0 ] } }, last24Count: { $sum: "$count" } } }, // 步骤3:整理客户数据结构 { $project: { _id: 0, name: "$_id.name", city: "$_id.city", last12Count: 1, last24Count: 1 } }, // 步骤4:聚合生成并排序截取Top客户列表 { $group: { _id: null, last12Hours: { $push: { name: "$name", city: "$city", count: "$last12Count" } }, last24Hours: { $push: { name: "$name", city: "$city", count: "$last24Count" } } } }, { $project: { _id: 0, last12Hours: { $slice: [{ $sortArray: { input: "$last12Hours", sortBy: { count: -1 } } }, 5] }, last24Hours: { $slice: [{ $sortArray: { input: "$last24Hours", sortBy: { count: -1 } } }, 5] } } } ])
兼容低版本MongoDB(5.0以下)的处理方式
如果你的MongoDB版本不支持$sortArray,可以用$unwind+$sort+$group来实现排序截取:
// 替换步骤4的两个阶段为以下内容 { $group: { _id: null, allClients: { $push: "$$ROOT" } } }, { $unwind: "$allClients" }, // 处理last12Hours的Top列表 { $sort: { "allClients.last12Count": -1 } }, { $group: { _id: null, allClients: { $push: "$$ROOT.allClients" }, last12Hours: { $push: { name: "$allClients.name", city: "$allClients.city", count: "$allClients.last12Count" } } } }, { $project: { allClients: 1, last12Hours: { $slice: ["$last12Hours", 5] } } }, // 处理last24Hours的Top列表 { $unwind: "$allClients" }, { $sort: { "allClients.last24Count": -1 } }, { $group: { _id: null, last12Hours: { $first: "$last12Hours" }, last24Hours: { $push: { name: "$allClients.name", city: "$allClients.city", count: "$allClients.last24Count" } } } }, { $project: { _id: 0, last12Hours: 1, last24Hours: { $slice: ["$last24Hours", 5] } } }
内容的提问来源于stack exchange,提问作者Wbe
相关产品推荐
相关产品推荐

