如何在Mongoose中对指定时间范围内的两个字段分别求和
Mongoose 统计指定时间范围借贷总额实现方案
核心思路
使用MongoDB聚合管道完成两个核心操作:
- 用
$match阶段筛选出时间落在指定范围内的所有台账文档 - 用
$group阶段对匹配到的文档的debitValue和creditValue字段做求和统计
完整实现代码
首先先基于你给出的Schema初始化Model:
const Ledger = mongoose.model('Ledger', ledgerSchema);
封装统计方法:
/** * 统计指定时间范围内的借贷总额 * @param {Date} startDate 统计开始时间 * @param {Date} endDate 统计结束时间 * @returns {Object} 包含totalDebit(借方总额)、totalCredit(贷方总额)的对象 */ const getLedgerTotalsByDateRange = async (startDate, endDate) => { const aggregateResult = await Ledger.aggregate([ { $match: { date: { $gte: startDate, $lte: endDate } } }, { $group: { _id: null, // 不按特定字段分组,全局统计 totalDebit: { $sum: "$debitValue" }, totalCredit: { $sum: "$creditValue" } } } ]); // 无匹配数据时返回默认值 return aggregateResult[0] || { totalDebit: 0, totalCredit: 0 }; }
调用示例
以统计2024自然年全年数据为例:
// 注意构造时间时匹配你业务的时区,以下示例为UTC时间 const startTime = new Date('2024-01-01T00:00:00.000Z'); const endTime = new Date('2024-12-31T23:59:59.999Z'); const totals = await getLedgerTotalsByDateRange(startTime, endTime); console.log('借方总额:', totals.totalDebit); console.log('贷方总额:', totals.totalCredit);
优化注意事项
- 给
date字段添加索引可大幅提升大数据量下的查询效率,建索引代码:ledgerSchema.index({ date: 1 }) - 如果字段存在非数值脏数据,可在求和时做类型转换避免统计异常:
totalDebit: { $sum: { $toDouble: "$debitValue" } } - 涉及时区的业务场景,需先将业务时间转换为对应UTC时间再传入方法,避免统计范围偏差
内容的提问来源于stack exchange,提问作者aziz aon
相关产品推荐
相关产品推荐

