如何修正Mongoose聚合查询:筛选1个月内到期的MongoDB产品数据
Mongoose聚合查询修正:筛选1个月内到期的产品
现有Schema
const schemaDB = mongoose.Schema({ product:{ type: String, }, DateOfInstallation: { type: Date }, standardWarranty: { type: Number }, extendedWarranty: { type: Number }, AMC:{ type: Number } })
需求
筛选从今日起1个月内到期的产品,到期计算逻辑:
- 总保障年限 = standardWarranty + extendedWarranty + AMC
- 到期日期 = DateOfInstallation + 总保障年限(年)
- 当到期日期与今日的间隔≤1个月时,返回该产品
原查询的问题
原聚合查询在$match阶段直接使用$add、$dateAdd等聚合表达式是错误的——$match阶段仅支持查询运算符,不能直接用聚合表达式定义字段。必须先通过$addFields计算中间字段,再执行筛选逻辑。
修正后的聚合查询
方案一:日期范围筛选(推荐,支持索引优化)
const datas = await DBModel.aggregate([ // 计算总保障年限和到期日期 { $addFields: { totalYears: { $add: ['$standardWarranty', '$extendedWarranty', '$AMC'] }, expiryDate: { $dateAdd: { startDate: '$DateOfInstallation', unit: 'year', amount: '$totalYears' } } } }, // 筛选到期日期在未来1个月内的记录 { $match: { expiryDate: { $gte: new Date(), $lte: new Date(new Date().setMonth(new Date().getMonth() + 1)) } } }, // 指定返回字段 { $project: { DateOfInstallation: 1, standardWarranty: 1, extendedWarranty: 1, AMC: 1 } }, // 按安装日期升序排序 { $sort: { DateOfInstallation: 1 } } ])
方案二:日期差计算(精确月份差判断)
如果需要严格计算“到期日期与今日的月份差≤1”,可使用$dateDiff结合$expr实现:
const datas = await DBModel.aggregate([ { $addFields: { totalYears: { $add: ['$standardWarranty', '$extendedWarranty', '$AMC'] }, expiryDate: { $dateAdd: { startDate: '$DateOfInstallation', unit: 'year', amount: '$totalYears' } } } }, { $match: { $expr: { $lte: [ { $dateDiff: { startDate: new Date(), endDate: '$expiryDate', unit: 'month' } }, 1 ] } } }, { $project: { DateOfInstallation: 1, standardWarranty: 1, extendedWarranty: 1, AMC: 1 } }, { $sort: { DateOfInstallation: 1 } } ])
修正说明
$addFields计算中间字段:先在管道中新增totalYears和expiryDate字段,基于文档原有数据完成计算,为后续筛选提供基础。$match阶段逻辑调整:方案一直接用日期范围匹配,更符合MongoDB查询优化规则;方案二通过$expr在$match中嵌入聚合表达式,实现精确的月份差判断。- 保留原有的投影与排序逻辑:按需保留
$project和$sort的原有逻辑,确保返回结果符合需求。
内容的提问来源于stack exchange,提问作者shree varshan
相关产品推荐
相关产品推荐

