MongoDB聚合需求:关联用户成功交易并计算阶梯奖励
MongoDB 交易奖励计算实现方案
核心思路
- 关联用户与对应成功交易,同时按交易时间排序确保首笔交易排在最前
- 遍历用户交易数组,根据交易在数组中的位置判断是否为首笔,分别计算奖励
完整聚合查询代码
db.users.aggregate([ // 关联成功交易并排序 { $lookup: { from: "transactions", localField: "_id", foreignField: "userId", as: "transactions", pipeline: [ { $match: { status: "success" } }, // 筛选成功状态的交易 { $sort: { createdAt: 1 } } // 按交易创建时间升序,首笔交易排首位 ] } }, // 计算奖励并格式化输出 { $project: { name: 1, transactions: { $map: { input: "$transactions", as: "tx", in: { _id: "$$tx._id", paidAmount: "$$tx.paidAmount", reward: { $cond: { // 判断是否为数组中的第一笔交易 if: { $eq: [{ $indexOfArray: ["$transactions._id", "$$tx._id"] }, 0] }, then: { $multiply: ["$$tx.paidAmount", 0.3] }, // 首笔交易奖励:0.3倍金额 else: { $multiply: ["$$tx.paidAmount", 0.1] } // 后续交易奖励:0.1倍金额 } } } } } } }, // 可选:过滤无成功交易的用户 { $match: { transactions: { $ne: [] } } } ])
代码解释
- $lookup阶段:通过用户
_id关联交易集合,同时过滤出成功交易并按时间排序,确保首笔交易处于数组第一位,为后续奖励计算提供判断依据。 - $project阶段:使用
$map遍历交易数组,通过$indexOfArray获取当前交易在数组中的索引,结合$cond条件判断,分别计算首笔和后续交易的奖励金额。 - 可选$match阶段:如果不需要保留无成功交易的用户,可以添加此阶段过滤掉空交易数组的用户。
预期输出示例
[ { "_id": 1, "name": "Stephen", "transactions": [ { "_id": 1, "paidAmount": 10, "reward": 3 }, { "_id": 3, "paidAmount": 20, "reward": 2 } ] }, { "_id": 2, "name": "Peter", "transactions": [ { "_id": 2, "paidAmount": 5, "reward": 0.15 } ] } ]
内容的提问来源于stack exchange,提问作者Ashish
相关产品推荐
相关产品推荐

