基于MongoDB聚合,通过库存变化求和计算已售商品数量
MongoDB计算已售商品总数量解决方案
可以通过MongoDB聚合管道中的$reduce操作符,在累加器中同时跟踪前一个库存值和累计销量来实现需求。以下是具体的聚合查询:
db.collection.aggregate([ { $project: { id: 1, units_sold: { $reduce: { input: { $sort: { "stock_history.ts": 1 } }, // 确保按时间升序排序 initialValue: { total: 0, prevStock: { $arrayElemAt: ["$stock_history.stock", 0] } // 初始化前一个库存为第一条记录的库存 }, in: { total: { $cond: [ { $lt: ["$$this.stock", "$$value.prevStock"] }, // 当前库存 < 前一个库存时,计算销量 { $add: ["$$value.total", { $subtract: ["$$value.prevStock", "$$this.stock"] }] }, "$$value.total" // 否则销量保持不变 ] }, prevStock: "$$this.stock" // 更新前一个库存为当前库存 } } } } }, { $project: { id: 1, units_sold: "$units_sold.total" // 提取最终累计销量 } } ])
逻辑说明:
- 排序确保时序:先用
$sort对stock_history按时间戳ts升序排列,保证库存记录按时间先后顺序处理。 - 初始化累加器:
initialValue中定义两个变量:total:累计销量,初始为0prevStock:前一条记录的库存值,初始为库存历史数组的第一个元素值
- 遍历计算销量:
- 每次遍历当前库存记录
$$this,比较$$this.stock和$$value.prevStock - 如果当前库存小于前一个库存,说明发生销售,将差值(前库存-当前库存)加到累计销量中
- 无论是否产生销量,都将
prevStock更新为当前库存,供下一次遍历使用
- 每次遍历当前库存记录
- 提取最终结果:最后一步
$project只保留id和计算完成的units_sold
针对示例文档的计算过程:
- 初始
prevStock=104,total=0 - 第二条记录
stock=104:不小于前库存,total保持0,prevStock更新为104 - 第三条记录
stock=74:74<104,total=0+(104-74)=30,prevStock更新为74 - 第四条记录
stock=84:84>74,total保持30,prevStock更新为84 - 最终输出
units_sold=30,与期望结果一致
内容的提问来源于stack exchange,提问作者Zx3s
相关产品推荐
相关产品推荐

