Mongoose/MongoDB按symbol分组统计TokenBalance的usdvalue总和聚合查询问题
Mongoose 聚合查询实现方案
完整代码示例
// 自定义查询时间范围 const startTime = new Date('2024-01-01'); // 替换为你的实际起始时间 const endTime = new Date('2024-02-01'); // 替换为你的实际结束时间 const result = await TokenBalance.aggregate([ // 1. 过滤指定时间范围内的文档,按创建时间筛选可替换为updatedAt { $match: { createdAt: { $gte: startTime, $lte: endTime } } }, // 可选:过滤掉balances为空数组的文档,避免无效运算 { $match: { 'balances.0': { $exists: true } } }, // 2. 打平balances数组,每个数组成员转为独立文档 { $unwind: '$balances' }, // 3. 按symbol分组,对同组的usdvalue求和 { $group: { _id: '$balances.symbol', totalUsdValue: { $sum: '$balances.usdvalue' } } }, // 4. 调整输出格式,匹配需求的返回结构 { $project: { _id: 0, symbol: '$_id', balance: { $round: ['$totalUsdValue', 3] } // 按需调整保留小数位数,不需要精度控制可直接写 balance: '$totalUsdValue' } } ]); // 输出的result就是你需要的结构 console.log(result);
各阶段逻辑说明
- $match阶段:优先过滤符合时间条件的文档,减少后续计算的数据量,提升查询性能。如果需要按文档更新时间筛选,将
createdAt替换为updatedAt即可。 - 可选过滤阶段:排除balances为空数组的文档,避免unwind操作生成无效空数据。
- $unwind阶段:将嵌套的balances数组拆分为单条独立文档,才能对每个balance对象的字段做分组统计。
- $group阶段:以balances.symbol作为分组唯一键,使用$sum运算符累加同分组下所有usdvalue的数值。
- $project阶段:调整输出字段,隐藏默认返回的_id字段,将分组键重命名为symbol,累加结果重命名为balance,同时支持通过$round控制返回数值的精度。
内容的提问来源于stack exchange,提问作者headliner090
相关产品推荐
相关产品推荐

